ndarray/
lib.rs

1// Copyright 2014-2020 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#![crate_name = "ndarray"]
9#![doc(html_root_url = "https://docs.rs/ndarray/0.15/")]
10#![doc(html_logo_url = "https://rust-ndarray.github.io/images/rust-ndarray_logo.svg")]
11#![allow(
12    unstable_name_collisions, // our `PointerExt` collides with upcoming inherent methods on `NonNull`
13    clippy::deref_addrof,
14    clippy::manual_map, // is not an error
15    clippy::while_let_on_iterator, // is not an error
16    clippy::from_iter_instead_of_collect, // using from_iter is good style
17    clippy::incompatible_msrv, // false positive PointerExt::offset
18)]
19#![doc(test(attr(deny(warnings))))]
20#![doc(test(attr(allow(unused_variables))))]
21#![doc(test(attr(allow(deprecated))))]
22#![cfg_attr(not(feature = "std"), no_std)]
23
24//! The `ndarray` crate provides an *n*-dimensional container for general elements
25//! and for numerics.
26//!
27//! In *n*-dimensional we include, for example, 1-dimensional rows or columns,
28//! 2-dimensional matrices, and higher dimensional arrays. If the array has *n*
29//! dimensions, then an element in the array is accessed by using that many indices.
30//! Each dimension is also called an *axis*.
31//!
32//! - **[`ArrayBase`]**:
33//!   The *n*-dimensional array type itself.<br>
34//!   It is used to implement both the owned arrays and the views; see its docs
35//!   for an overview of all array features.<br>
36//! - The main specific array type is **[`Array`]**, which owns
37//!   its elements.
38//!
39//! ## Highlights
40//!
41//! - Generic *n*-dimensional array
42//! - [Slicing](ArrayBase#slicing), also with arbitrary step size, and negative
43//!   indices to mean elements from the end of the axis.
44//! - Views and subviews of arrays; iterators that yield subviews.
45//! - Higher order operations and arithmetic are performant
46//! - Array views can be used to slice and mutate any `[T]` data using
47//!   `ArrayView::from` and `ArrayViewMut::from`.
48//! - [`Zip`] for lock step function application across two or more arrays or other
49//!   item producers ([`NdProducer`] trait).
50//!
51//! ## Crate Status
52//!
53//! - Still iterating on and evolving the crate
54//!   + The crate is continuously developing, and breaking changes are expected
55//!     during evolution from version to version. We adopt the newest stable
56//!     rust features if we need them.
57//!   + Note that functions/methods/traits/etc. hidden from the docs are not
58//!     considered part of the public API, so changes to them are not
59//!     considered breaking changes.
60//! - Performance:
61//!   + Prefer higher order methods and arithmetic operations on arrays first,
62//!     then iteration, and as a last priority using indexed algorithms.
63//!   + The higher order functions like [`.map()`](ArrayBase::map),
64//!     [`.map_inplace()`](ArrayBase::map_inplace), [`.zip_mut_with()`](ArrayBase::zip_mut_with),
65//!     [`Zip`] and [`azip!()`](azip) are the most efficient ways
66//!     to perform single traversal and lock step traversal respectively.
67//!   + Performance of an operation depends on the memory layout of the array
68//!     or array view. Especially if it's a binary operation, which
69//!     needs matching memory layout to be efficient (with some exceptions).
70//!   + Efficient floating point matrix multiplication even for very large
71//!     matrices; can optionally use BLAS to improve it further.
72//!
73//! - **MSRV: Requires Rust 1.64 or later**
74//!
75//! ## Crate Feature Flags
76//!
77//! The following crate feature flags are available. They are configured in your
78//! `Cargo.toml`. See [`doc::crate_feature_flags`] for more information.
79//!
80//! - `std`: Rust standard library-using functionality (enabled by default)
81//! - `serde`: serialization support for serde 1.x
82//! - `rayon`: Parallel iterators, parallelized methods, the [`parallel`] module and [`par_azip!`].
83//! - `approx` Implementations of traits from the [`approx`] crate.
84//! - `blas`: transparent BLAS support for matrix multiplication, needs configuration.
85//! - `matrixmultiply-threading`: Use threading from `matrixmultiply`.
86//!
87//! ## Documentation
88//!
89//! * The docs for [`ArrayBase`] provide an overview of
90//!   the *n*-dimensional array type. Other good pages to look at are the
91//!   documentation for the [`s![]`](s!) and
92//!   [`azip!()`](azip!) macros.
93//!
94//! * If you have experience with NumPy, you may also be interested in
95//!   [`ndarray_for_numpy_users`](doc::ndarray_for_numpy_users).
96//!
97//! ## The ndarray ecosystem
98//!
99//! `ndarray` provides a lot of functionality, but it's not a one-stop solution.
100//!
101//! `ndarray` includes matrix multiplication and other binary/unary operations out of the box.
102//! More advanced linear algebra routines (e.g. SVD decomposition or eigenvalue computation)
103//! can be found in [`ndarray-linalg`](https://crates.io/crates/ndarray-linalg).
104//!
105//! The same holds for statistics: `ndarray` provides some basic functionalities (e.g. `mean`)
106//! but more advanced routines can be found in [`ndarray-stats`](https://crates.io/crates/ndarray-stats).
107//!
108//! If you are looking to generate random arrays instead, check out [`ndarray-rand`](https://crates.io/crates/ndarray-rand).
109//!
110//! For conversion between `ndarray`, [`nalgebra`](https://crates.io/crates/nalgebra) and
111//! [`image`](https://crates.io/crates/image) check out [`nshare`](https://crates.io/crates/nshare).
112
113extern crate alloc;
114
115#[cfg(not(feature = "std"))]
116extern crate core as std;
117#[cfg(feature = "std")]
118extern crate std;
119
120#[cfg(feature = "blas")]
121extern crate cblas_sys;
122
123#[cfg(feature = "docs")]
124pub mod doc;
125
126#[cfg(target_has_atomic = "ptr")]
127use alloc::sync::Arc;
128
129#[cfg(not(target_has_atomic = "ptr"))]
130use portable_atomic_util::Arc;
131
132use std::marker::PhantomData;
133
134pub use crate::dimension::dim::*;
135pub use crate::dimension::{Axis, AxisDescription, Dimension, IntoDimension, RemoveAxis};
136pub use crate::dimension::{DimAdd, DimMax};
137
138pub use crate::dimension::IxDynImpl;
139pub use crate::dimension::NdIndex;
140pub use crate::error::{ErrorKind, ShapeError};
141pub use crate::indexes::{indices, indices_of};
142pub use crate::order::Order;
143pub use crate::slice::{MultiSliceArg, NewAxis, Slice, SliceArg, SliceInfo, SliceInfoElem, SliceNextDim};
144
145use crate::iterators::Baseiter;
146use crate::iterators::{ElementsBase, ElementsBaseMut, Iter, IterMut};
147
148pub use crate::arraytraits::AsArray;
149pub use crate::linalg_traits::LinalgScalar;
150#[cfg(feature = "std")]
151pub use crate::linalg_traits::NdFloat;
152
153pub use crate::stacking::{concatenate, stack};
154
155pub use crate::impl_views::IndexLonger;
156pub use crate::math_cell::MathCell;
157pub use crate::shape_builder::{Shape, ShapeArg, ShapeBuilder, StrideShape};
158
159#[macro_use]
160mod macro_utils;
161#[macro_use]
162mod private;
163mod aliases;
164#[macro_use]
165mod itertools;
166mod argument_traits;
167#[cfg(feature = "serde")]
168mod array_serde;
169mod arrayformat;
170mod arraytraits;
171pub use crate::argument_traits::AssignElem;
172mod data_repr;
173mod data_traits;
174
175pub use crate::aliases::*;
176
177pub use crate::data_traits::{Data, DataMut, DataOwned, DataShared, RawData, RawDataClone, RawDataMut, RawDataSubst};
178
179mod free_functions;
180pub use crate::free_functions::*;
181pub use crate::iterators::iter;
182
183mod error;
184mod extension;
185mod geomspace;
186mod indexes;
187mod iterators;
188mod layout;
189mod linalg_traits;
190mod linspace;
191#[cfg(feature = "std")]
192pub use crate::linspace::{linspace, range, Linspace};
193mod logspace;
194#[cfg(feature = "std")]
195pub use crate::logspace::{logspace, Logspace};
196mod math_cell;
197mod numeric_util;
198mod order;
199mod partial;
200mod shape_builder;
201#[macro_use]
202mod slice;
203mod split_at;
204mod stacking;
205mod low_level_util;
206#[macro_use]
207mod zip;
208
209mod dimension;
210
211pub use crate::zip::{FoldWhile, IntoNdProducer, NdProducer, Zip};
212
213pub use crate::layout::Layout;
214
215/// Implementation's prelude. Common types used everywhere.
216mod imp_prelude
217{
218    pub use crate::dimension::DimensionExt;
219    pub use crate::prelude::*;
220    pub use crate::ArcArray;
221    pub use crate::{
222        CowRepr,
223        Data,
224        DataMut,
225        DataOwned,
226        DataShared,
227        Ix,
228        Ixs,
229        RawData,
230        RawDataMut,
231        RawViewRepr,
232        RemoveAxis,
233        ViewRepr,
234    };
235}
236
237pub mod prelude;
238
239/// Array index type
240pub type Ix = usize;
241/// Array index type (signed)
242pub type Ixs = isize;
243
244/// An *n*-dimensional array.
245///
246/// The array is a general container of elements.
247/// The array supports arithmetic operations by applying them elementwise, if the
248/// elements are numeric, but it supports non-numeric elements too.
249///
250/// The arrays rarely grow or shrink, since those operations can be costly. On
251/// the other hand there is a rich set of methods and operations for taking views,
252/// slices, and making traversals over one or more arrays.
253///
254/// In *n*-dimensional we include for example 1-dimensional rows or columns,
255/// 2-dimensional matrices, and higher dimensional arrays. If the array has *n*
256/// dimensions, then an element is accessed by using that many indices.
257///
258/// The `ArrayBase<S, D>` is parameterized by `S` for the data container and
259/// `D` for the dimensionality.
260///
261/// Type aliases [`Array`], [`ArcArray`], [`CowArray`], [`ArrayView`], and
262/// [`ArrayViewMut`] refer to `ArrayBase` with different types for the data
263/// container: arrays with different kinds of ownership or different kinds of array views.
264///
265/// ## Contents
266///
267/// + [Array](#array)
268/// + [ArcArray](#arcarray)
269/// + [CowArray](#cowarray)
270/// + [Array Views](#array-views)
271/// + [Indexing and Dimension](#indexing-and-dimension)
272/// + [Loops, Producers and Iterators](#loops-producers-and-iterators)
273/// + [Slicing](#slicing)
274/// + [Subviews](#subviews)
275/// + [Arithmetic Operations](#arithmetic-operations)
276/// + [Broadcasting](#broadcasting)
277/// + [Conversions](#conversions)
278/// + [Constructor Methods for Owned Arrays](#constructor-methods-for-owned-arrays)
279/// + [Methods For All Array Types](#methods-for-all-array-types)
280/// + [Methods For 1-D Arrays](#methods-for-1-d-arrays)
281/// + [Methods For 2-D Arrays](#methods-for-2-d-arrays)
282/// + [Methods for Dynamic-Dimensional Arrays](#methods-for-dynamic-dimensional-arrays)
283/// + [Numerical Methods for Arrays](#numerical-methods-for-arrays)
284///
285/// ## `Array`
286///
287/// [`Array`] is an owned array that owns the underlying array
288/// elements directly (just like a `Vec`) and it is the default way to create and
289/// store n-dimensional data. `Array<A, D>` has two type parameters: `A` for
290/// the element type, and `D` for the dimensionality. A particular
291/// dimensionality's type alias like `Array3<A>` just has the type parameter
292/// `A` for element type.
293///
294/// An example:
295///
296/// ```
297/// // Create a three-dimensional f64 array, initialized with zeros
298/// use ndarray::Array3;
299/// let mut temperature = Array3::<f64>::zeros((3, 4, 5));
300/// // Increase the temperature in this location
301/// temperature[[2, 2, 2]] += 0.5;
302/// ```
303///
304/// ## `ArcArray`
305///
306/// [`ArcArray`] is an owned array with reference counted
307/// data (shared ownership).
308/// Sharing requires that it uses copy-on-write for mutable operations.
309/// Calling a method for mutating elements on `ArcArray`, for example
310/// [`view_mut()`](Self::view_mut) or [`get_mut()`](Self::get_mut),
311/// will break sharing and require a clone of the data (if it is not uniquely held).
312///
313/// ## `CowArray`
314///
315/// [`CowArray`] is analogous to [`std::borrow::Cow`].
316/// It can represent either an immutable view or a uniquely owned array. If a
317/// `CowArray` instance is the immutable view variant, then calling a method
318/// for mutating elements in the array will cause it to be converted into the
319/// owned variant (by cloning all the elements) before the modification is
320/// performed.
321///
322/// ## Array Views
323///
324/// [`ArrayView`] and [`ArrayViewMut`] are read-only and read-write array views
325/// respectively. They use dimensionality, indexing, and almost all other
326/// methods the same way as the other array types.
327///
328/// Methods for `ArrayBase` apply to array views too, when the trait bounds
329/// allow.
330///
331/// Please see the documentation for the respective array view for an overview
332/// of methods specific to array views: [`ArrayView`], [`ArrayViewMut`].
333///
334/// A view is created from an array using [`.view()`](ArrayBase::view),
335/// [`.view_mut()`](ArrayBase::view_mut), using
336/// slicing ([`.slice()`](ArrayBase::slice), [`.slice_mut()`](ArrayBase::slice_mut)) or from one of
337/// the many iterators that yield array views.
338///
339/// You can also create an array view from a regular slice of data not
340/// allocated with `Array` — see array view methods or their `From` impls.
341///
342/// Note that all `ArrayBase` variants can change their view (slicing) of the
343/// data freely, even when their data can’t be mutated.
344///
345/// ## Indexing and Dimension
346///
347/// The dimensionality of the array determines the number of *axes*, for example
348/// a 2D array has two axes. These are listed in “big endian” order, so that
349/// the greatest dimension is listed first, the lowest dimension with the most
350/// rapidly varying index is the last.
351///
352/// In a 2D array the index of each element is `[row, column]` as seen in this
353/// 4 × 3 example:
354///
355/// ```ignore
356/// [[ [0, 0], [0, 1], [0, 2] ],  // row 0
357///  [ [1, 0], [1, 1], [1, 2] ],  // row 1
358///  [ [2, 0], [2, 1], [2, 2] ],  // row 2
359///  [ [3, 0], [3, 1], [3, 2] ]]  // row 3
360/// //    \       \       \
361/// //   column 0  \     column 2
362/// //            column 1
363/// ```
364///
365/// The number of axes for an array is fixed by its `D` type parameter: `Ix1`
366/// for a 1D array, `Ix2` for a 2D array etc. The dimension type `IxDyn` allows
367/// a dynamic number of axes.
368///
369/// A fixed size array (`[usize; N]`) of the corresponding dimensionality is
370/// used to index the `Array`, making the syntax `array[[` i, j,  ...`]]`
371///
372/// ```
373/// use ndarray::Array2;
374/// let mut array = Array2::zeros((4, 3));
375/// array[[1, 1]] = 7;
376/// ```
377///
378/// Important traits and types for dimension and indexing:
379///
380/// - A [`struct@Dim`] value represents a dimensionality or index.
381/// - Trait [`Dimension`] is implemented by all
382///   dimensionalities. It defines many operations for dimensions and indices.
383/// - Trait [`IntoDimension`] is used to convert into a
384///   `Dim` value.
385/// - Trait [`ShapeBuilder`] is an extension of
386///   `IntoDimension` and is used when constructing an array. A shape describes
387///   not just the extent of each axis but also their strides.
388/// - Trait [`NdIndex`] is an extension of `Dimension` and is
389///   for values that can be used with indexing syntax.
390///
391///
392/// The default memory order of an array is *row major* order (a.k.a “c” order),
393/// where each row is contiguous in memory.
394/// A *column major* (a.k.a. “f” or fortran) memory order array has
395/// columns (or, in general, the outermost axis) with contiguous elements.
396///
397/// The logical order of any array’s elements is the row major order
398/// (the rightmost index is varying the fastest).
399/// The iterators `.iter(), .iter_mut()` always adhere to this order, for example.
400///
401/// ## Loops, Producers and Iterators
402///
403/// Using [`Zip`] is the most general way to apply a procedure
404/// across one or several arrays or *producers*.
405///
406/// [`NdProducer`] is like an iterable but for
407/// multidimensional data. All producers have dimensions and axes, like an
408/// array view, and they can be split and used with parallelization using `Zip`.
409///
410/// For example, `ArrayView<A, D>` is a producer, it has the same dimensions
411/// as the array view and for each iteration it produces a reference to
412/// the array element (`&A` in this case).
413///
414/// Another example, if we have a 10 × 10 array and use `.exact_chunks((2, 2))`
415/// we get a producer of chunks which has the dimensions 5 × 5 (because
416/// there are *10 / 2 = 5* chunks in either direction). The 5 × 5 chunks producer
417/// can be paired with any other producers of the same dimension with `Zip`, for
418/// example 5 × 5 arrays.
419///
420/// ### `.iter()` and `.iter_mut()`
421///
422/// These are the element iterators of arrays and they produce an element
423/// sequence in the logical order of the array, that means that the elements
424/// will be visited in the sequence that corresponds to increasing the
425/// last index first: *0, ..., 0,  0*; *0, ..., 0, 1*; *0, ...0, 2* and so on.
426///
427/// ### `.outer_iter()` and `.axis_iter()`
428///
429/// These iterators produce array views of one smaller dimension.
430///
431/// For example, for a 2D array, `.outer_iter()` will produce the 1D rows.
432/// For a 3D array, `.outer_iter()` produces 2D subviews.
433///
434/// `.axis_iter()` is like `outer_iter()` but allows you to pick which
435/// axis to traverse.
436///
437/// The `outer_iter` and `axis_iter` are one dimensional producers.
438///
439/// ## `.rows()`, `.columns()` and `.lanes()`
440///
441/// [`.rows()`][gr] is a producer (and iterable) of all rows in an array.
442///
443/// ```
444/// use ndarray::Array;
445///
446/// // 1. Loop over the rows of a 2D array
447/// let mut a = Array::zeros((10, 10));
448/// for mut row in a.rows_mut() {
449///     row.fill(1.);
450/// }
451///
452/// // 2. Use Zip to pair each row in 2D `a` with elements in 1D `b`
453/// use ndarray::Zip;
454/// let mut b = Array::zeros(a.nrows());
455///
456/// Zip::from(a.rows())
457///     .and(&mut b)
458///     .for_each(|a_row, b_elt| {
459///         *b_elt = a_row[a.ncols() - 1] - a_row[0];
460///     });
461/// ```
462///
463/// The *lanes* of an array are 1D segments along an axis and when pointed
464/// along the last axis they are *rows*, when pointed along the first axis
465/// they are *columns*.
466///
467/// A *m* × *n* array has *m* rows each of length *n* and conversely
468/// *n* columns each of length *m*.
469///
470/// To generalize this, we say that an array of dimension *a* × *m* × *n*
471/// has *a m* rows. It's composed of *a* times the previous array, so it
472/// has *a* times as many rows.
473///
474/// All methods: [`.rows()`][gr], [`.rows_mut()`][grm],
475/// [`.columns()`][gc], [`.columns_mut()`][gcm],
476/// [`.lanes(axis)`][l], [`.lanes_mut(axis)`][lm].
477///
478/// [gr]: Self::rows
479/// [grm]: Self::rows_mut
480/// [gc]: Self::columns
481/// [gcm]: Self::columns_mut
482/// [l]: Self::lanes
483/// [lm]: Self::lanes_mut
484///
485/// Yes, for 2D arrays `.rows()` and `.outer_iter()` have about the same
486/// effect:
487///
488///  + `rows()` is a producer with *n* - 1 dimensions of 1 dimensional items
489///  + `outer_iter()` is a producer with 1 dimension of *n* - 1 dimensional items
490///
491/// ## Slicing
492///
493/// You can use slicing to create a view of a subset of the data in
494/// the array. Slicing methods include [`.slice()`], [`.slice_mut()`],
495/// [`.slice_move()`], and [`.slice_collapse()`].
496///
497/// The slicing argument can be passed using the macro [`s![]`](s!),
498/// which will be used in all examples. (The explicit form is an instance of
499/// [`SliceInfo`] or another type which implements [`SliceArg`]; see their docs
500/// for more information.)
501///
502/// If a range is used, the axis is preserved. If an index is used, that index
503/// is selected and the axis is removed; this selects a subview. See
504/// [*Subviews*](#subviews) for more information about subviews. If a
505/// [`NewAxis`] instance is used, a new axis is inserted. Note that
506/// [`.slice_collapse()`] panics on `NewAxis` elements and behaves like
507/// [`.collapse_axis()`] by preserving the number of dimensions.
508///
509/// [`.slice()`]: Self::slice
510/// [`.slice_mut()`]: Self::slice_mut
511/// [`.slice_move()`]: Self::slice_move
512/// [`.slice_collapse()`]: Self::slice_collapse
513///
514/// When slicing arrays with generic dimensionality, creating an instance of
515/// [`SliceInfo`] to pass to the multi-axis slicing methods like [`.slice()`]
516/// is awkward. In these cases, it's usually more convenient to use
517/// [`.slice_each_axis()`]/[`.slice_each_axis_mut()`]/[`.slice_each_axis_inplace()`]
518/// or to create a view and then slice individual axes of the view using
519/// methods such as [`.slice_axis_inplace()`] and [`.collapse_axis()`].
520///
521/// [`.slice_each_axis()`]: Self::slice_each_axis
522/// [`.slice_each_axis_mut()`]: Self::slice_each_axis_mut
523/// [`.slice_each_axis_inplace()`]: Self::slice_each_axis_inplace
524/// [`.slice_axis_inplace()`]: Self::slice_axis_inplace
525/// [`.collapse_axis()`]: Self::collapse_axis
526///
527/// It's possible to take multiple simultaneous *mutable* slices with
528/// [`.multi_slice_mut()`] or (for [`ArrayViewMut`] only)
529/// [`.multi_slice_move()`].
530///
531/// [`.multi_slice_mut()`]: Self::multi_slice_mut
532/// [`.multi_slice_move()`]: ArrayViewMut#method.multi_slice_move
533///
534/// ```
535/// use ndarray::{arr2, arr3, s, ArrayBase, DataMut, Dimension, NewAxis, Slice};
536///
537/// // 2 submatrices of 2 rows with 3 elements per row, means a shape of `[2, 2, 3]`.
538///
539/// let a = arr3(&[[[ 1,  2,  3],     // -- 2 rows  \_
540///                 [ 4,  5,  6]],    // --         /
541///                [[ 7,  8,  9],     //            \_ 2 submatrices
542///                 [10, 11, 12]]]);  //            /
543/// //  3 columns ..../.../.../
544///
545/// assert_eq!(a.shape(), &[2, 2, 3]);
546///
547/// // Let’s create a slice with
548/// //
549/// // - Both of the submatrices of the greatest dimension: `..`
550/// // - Only the first row in each submatrix: `0..1`
551/// // - Every element in each row: `..`
552///
553/// let b = a.slice(s![.., 0..1, ..]);
554/// let c = arr3(&[[[ 1,  2,  3]],
555///                [[ 7,  8,  9]]]);
556/// assert_eq!(b, c);
557/// assert_eq!(b.shape(), &[2, 1, 3]);
558///
559/// // Let’s create a slice with
560/// //
561/// // - Both submatrices of the greatest dimension: `..`
562/// // - The last row in each submatrix: `-1..`
563/// // - Row elements in reverse order: `..;-1`
564/// let d = a.slice(s![.., -1.., ..;-1]);
565/// let e = arr3(&[[[ 6,  5,  4]],
566///                [[12, 11, 10]]]);
567/// assert_eq!(d, e);
568/// assert_eq!(d.shape(), &[2, 1, 3]);
569///
570/// // Let’s create a slice while selecting a subview and inserting a new axis with
571/// //
572/// // - Both submatrices of the greatest dimension: `..`
573/// // - The last row in each submatrix, removing that axis: `-1`
574/// // - Row elements in reverse order: `..;-1`
575/// // - A new axis at the end.
576/// let f = a.slice(s![.., -1, ..;-1, NewAxis]);
577/// let g = arr3(&[[ [6],  [5],  [4]],
578///                [[12], [11], [10]]]);
579/// assert_eq!(f, g);
580/// assert_eq!(f.shape(), &[2, 3, 1]);
581///
582/// // Let's take two disjoint, mutable slices of a matrix with
583/// //
584/// // - One containing all the even-index columns in the matrix
585/// // - One containing all the odd-index columns in the matrix
586/// let mut h = arr2(&[[0, 1, 2, 3],
587///                    [4, 5, 6, 7]]);
588/// let (s0, s1) = h.multi_slice_mut((s![.., ..;2], s![.., 1..;2]));
589/// let i = arr2(&[[0, 2],
590///                [4, 6]]);
591/// let j = arr2(&[[1, 3],
592///                [5, 7]]);
593/// assert_eq!(s0, i);
594/// assert_eq!(s1, j);
595///
596/// // Generic function which assigns the specified value to the elements which
597/// // have indices in the lower half along all axes.
598/// fn fill_lower<S, D>(arr: &mut ArrayBase<S, D>, x: S::Elem)
599/// where
600///     S: DataMut,
601///     S::Elem: Clone,
602///     D: Dimension,
603/// {
604///     arr.slice_each_axis_mut(|ax| Slice::from(0..ax.len / 2)).fill(x);
605/// }
606/// fill_lower(&mut h, 9);
607/// let k = arr2(&[[9, 9, 2, 3],
608///                [4, 5, 6, 7]]);
609/// assert_eq!(h, k);
610/// ```
611///
612/// ## Subviews
613///
614/// Subview methods allow you to restrict the array view while removing one
615/// axis from the array. Methods for selecting individual subviews include
616/// [`.index_axis()`], [`.index_axis_mut()`], [`.index_axis_move()`], and
617/// [`.index_axis_inplace()`]. You can also select a subview by using a single
618/// index instead of a range when slicing. Some other methods, such as
619/// [`.fold_axis()`], [`.axis_iter()`], [`.axis_iter_mut()`],
620/// [`.outer_iter()`], and [`.outer_iter_mut()`] operate on all the subviews
621/// along an axis.
622///
623/// A related method is [`.collapse_axis()`], which modifies the view in the
624/// same way as [`.index_axis()`] except for removing the collapsed axis, since
625/// it operates *in place*. The length of the axis becomes 1.
626///
627/// Methods for selecting an individual subview take two arguments: `axis` and
628/// `index`.
629///
630/// [`.axis_iter()`]: Self::axis_iter
631/// [`.axis_iter_mut()`]: Self::axis_iter_mut
632/// [`.fold_axis()`]: Self::fold_axis
633/// [`.index_axis()`]: Self::index_axis
634/// [`.index_axis_inplace()`]: Self::index_axis_inplace
635/// [`.index_axis_mut()`]: Self::index_axis_mut
636/// [`.index_axis_move()`]: Self::index_axis_move
637/// [`.collapse_axis()`]: Self::collapse_axis
638/// [`.outer_iter()`]: Self::outer_iter
639/// [`.outer_iter_mut()`]: Self::outer_iter_mut
640///
641/// ```
642///
643/// use ndarray::{arr3, aview1, aview2, s, Axis};
644///
645///
646/// // 2 submatrices of 2 rows with 3 elements per row, means a shape of `[2, 2, 3]`.
647///
648/// let a = arr3(&[[[ 1,  2,  3],    // \ axis 0, submatrix 0
649///                 [ 4,  5,  6]],   // /
650///                [[ 7,  8,  9],    // \ axis 0, submatrix 1
651///                 [10, 11, 12]]]); // /
652///         //        \
653///         //         axis 2, column 0
654///
655/// assert_eq!(a.shape(), &[2, 2, 3]);
656///
657/// // Let’s take a subview along the greatest dimension (axis 0),
658/// // taking submatrix 0, then submatrix 1
659///
660/// let sub_0 = a.index_axis(Axis(0), 0);
661/// let sub_1 = a.index_axis(Axis(0), 1);
662///
663/// assert_eq!(sub_0, aview2(&[[ 1,  2,  3],
664///                            [ 4,  5,  6]]));
665/// assert_eq!(sub_1, aview2(&[[ 7,  8,  9],
666///                            [10, 11, 12]]));
667/// assert_eq!(sub_0.shape(), &[2, 3]);
668///
669/// // This is the subview picking only axis 2, column 0
670/// let sub_col = a.index_axis(Axis(2), 0);
671///
672/// assert_eq!(sub_col, aview2(&[[ 1,  4],
673///                              [ 7, 10]]));
674///
675/// // You can take multiple subviews at once (and slice at the same time)
676/// let double_sub = a.slice(s![1, .., 0]);
677/// assert_eq!(double_sub, aview1(&[7, 10]));
678/// ```
679///
680/// ## Arithmetic Operations
681///
682/// Arrays support all arithmetic operations the same way: they apply elementwise.
683///
684/// Since the trait implementations are hard to overview, here is a summary.
685///
686/// ### Binary Operators with Two Arrays
687///
688/// Let `A` be an array or view of any kind. Let `B` be an array
689/// with owned storage (either `Array` or `ArcArray`).
690/// Let `C` be an array with mutable data (either `Array`, `ArcArray`
691/// or `ArrayViewMut`).
692/// The following combinations of operands
693/// are supported for an arbitrary binary operator denoted by `@` (it can be
694/// `+`, `-`, `*`, `/` and so on).
695///
696/// - `&A @ &A` which produces a new `Array`
697/// - `B @ A` which consumes `B`, updates it with the result, and returns it
698/// - `B @ &A` which consumes `B`, updates it with the result, and returns it
699/// - `C @= &A` which performs an arithmetic operation in place
700///
701/// Note that the element type needs to implement the operator trait and the
702/// `Clone` trait.
703///
704/// ```
705/// use ndarray::{array, ArrayView1};
706///
707/// let owned1 = array![1, 2];
708/// let owned2 = array![3, 4];
709/// let view1 = ArrayView1::from(&[5, 6]);
710/// let view2 = ArrayView1::from(&[7, 8]);
711/// let mut mutable = array![9, 10];
712///
713/// let sum1 = &view1 + &view2;   // Allocates a new array. Note the explicit `&`.
714/// // let sum2 = view1 + &view2; // This doesn't work because `view1` is not an owned array.
715/// let sum3 = owned1 + view1;    // Consumes `owned1`, updates it, and returns it.
716/// let sum4 = owned2 + &view2;   // Consumes `owned2`, updates it, and returns it.
717/// mutable += &view2;            // Updates `mutable` in-place.
718/// ```
719///
720/// ### Binary Operators with Array and Scalar
721///
722/// The trait [`ScalarOperand`] marks types that can be used in arithmetic
723/// with arrays directly. For a scalar `K` the following combinations of operands
724/// are supported (scalar can be on either the left or right side, but
725/// `ScalarOperand` docs has the detailed conditions).
726///
727/// - `&A @ K` or `K @ &A` which produces a new `Array`
728/// - `B @ K` or `K @ B` which consumes `B`, updates it with the result and returns it
729/// - `C @= K` which performs an arithmetic operation in place
730///
731/// ### Unary Operators
732///
733/// Let `A` be an array or view of any kind. Let `B` be an array with owned
734/// storage (either `Array` or `ArcArray`). The following operands are supported
735/// for an arbitrary unary operator denoted by `@` (it can be `-` or `!`).
736///
737/// - `@&A` which produces a new `Array`
738/// - `@B` which consumes `B`, updates it with the result, and returns it
739///
740/// ## Broadcasting
741///
742/// Arrays support limited *broadcasting*, where arithmetic operations with
743/// array operands of different sizes can be carried out by repeating the
744/// elements of the smaller dimension array. See
745/// [`.broadcast()`](Self::broadcast) for a more detailed
746/// description.
747///
748/// ```
749/// use ndarray::arr2;
750///
751/// let a = arr2(&[[1., 1.],
752///                [1., 2.],
753///                [0., 3.],
754///                [0., 4.]]);
755///
756/// let b = arr2(&[[0., 1.]]);
757///
758/// let c = arr2(&[[1., 2.],
759///                [1., 3.],
760///                [0., 4.],
761///                [0., 5.]]);
762/// // We can add because the shapes are compatible even if not equal.
763/// // The `b` array is shape 1 × 2 but acts like a 4 × 2 array.
764/// assert!(
765///     c == a + b
766/// );
767/// ```
768///
769/// ## Conversions
770///
771/// ### Conversions Between Array Types
772///
773/// This table is a summary of the conversions between arrays of different
774/// ownership, dimensionality, and element type. All of the conversions in this
775/// table preserve the shape of the array.
776///
777/// <table>
778/// <tr>
779/// <th rowspan="2">Output</th>
780/// <th colspan="5">Input</th>
781/// </tr>
782///
783/// <tr>
784/// <td>
785///
786/// `Array<A, D>`
787///
788/// </td>
789/// <td>
790///
791/// `ArcArray<A, D>`
792///
793/// </td>
794/// <td>
795///
796/// `CowArray<'a, A, D>`
797///
798/// </td>
799/// <td>
800///
801/// `ArrayView<'a, A, D>`
802///
803/// </td>
804/// <td>
805///
806/// `ArrayViewMut<'a, A, D>`
807///
808/// </td>
809/// </tr>
810///
811/// <!--Conversions to `Array<A, D>`-->
812///
813/// <tr>
814/// <td>
815///
816/// `Array<A, D>`
817///
818/// </td>
819/// <td>
820///
821/// no-op
822///
823/// </td>
824/// <td>
825///
826/// [`a.into_owned()`][.into_owned()]
827///
828/// </td>
829/// <td>
830///
831/// [`a.into_owned()`][.into_owned()]
832///
833/// </td>
834/// <td>
835///
836/// [`a.to_owned()`][.to_owned()]
837///
838/// </td>
839/// <td>
840///
841/// [`a.to_owned()`][.to_owned()]
842///
843/// </td>
844/// </tr>
845///
846/// <!--Conversions to `ArcArray<A, D>`-->
847///
848/// <tr>
849/// <td>
850///
851/// `ArcArray<A, D>`
852///
853/// </td>
854/// <td>
855///
856/// [`a.into_shared()`][.into_shared()]
857///
858/// </td>
859/// <td>
860///
861/// no-op
862///
863/// </td>
864/// <td>
865///
866/// [`a.into_owned().into_shared()`][.into_shared()]
867///
868/// </td>
869/// <td>
870///
871/// [`a.to_owned().into_shared()`][.into_shared()]
872///
873/// </td>
874/// <td>
875///
876/// [`a.to_owned().into_shared()`][.into_shared()]
877///
878/// </td>
879/// </tr>
880///
881/// <!--Conversions to `CowArray<'a, A, D>`-->
882///
883/// <tr>
884/// <td>
885///
886/// `CowArray<'a, A, D>`
887///
888/// </td>
889/// <td>
890///
891/// [`CowArray::from(a)`](CowArray#impl-From<ArrayBase<OwnedRepr<A>%2C%20D>>)
892///
893/// </td>
894/// <td>
895///
896/// [`CowArray::from(a.into_owned())`](CowArray#impl-From<ArrayBase<OwnedRepr<A>%2C%20D>>)
897///
898/// </td>
899/// <td>
900///
901/// no-op
902///
903/// </td>
904/// <td>
905///
906/// [`CowArray::from(a)`](CowArray#impl-From<ArrayBase<ViewRepr<%26%27a%20A>%2C%20D>>)
907///
908/// </td>
909/// <td>
910///
911/// [`CowArray::from(a.view())`](CowArray#impl-From<ArrayBase<ViewRepr<%26%27a%20A>%2C%20D>>)
912///
913/// </td>
914/// </tr>
915///
916/// <!--Conversions to `ArrayView<'b, A, D>`-->
917///
918/// <tr>
919/// <td>
920///
921/// `ArrayView<'b, A, D>`
922///
923/// </td>
924/// <td>
925///
926/// [`a.view()`][.view()]
927///
928/// </td>
929/// <td>
930///
931/// [`a.view()`][.view()]
932///
933/// </td>
934/// <td>
935///
936/// [`a.view()`][.view()]
937///
938/// </td>
939/// <td>
940///
941/// [`a.view()`][.view()] or [`a.reborrow()`][ArrayView::reborrow()]
942///
943/// </td>
944/// <td>
945///
946/// [`a.view()`][.view()]
947///
948/// </td>
949/// </tr>
950///
951/// <!--Conversions to `ArrayViewMut<'b, A, D>`-->
952///
953/// <tr>
954/// <td>
955///
956/// `ArrayViewMut<'b, A, D>`
957///
958/// </td>
959/// <td>
960///
961/// [`a.view_mut()`][.view_mut()]
962///
963/// </td>
964/// <td>
965///
966/// [`a.view_mut()`][.view_mut()]
967///
968/// </td>
969/// <td>
970///
971/// [`a.view_mut()`][.view_mut()]
972///
973/// </td>
974/// <td>
975///
976/// illegal
977///
978/// </td>
979/// <td>
980///
981/// [`a.view_mut()`][.view_mut()] or [`a.reborrow()`][ArrayViewMut::reborrow()]
982///
983/// </td>
984/// </tr>
985///
986/// <!--Conversions to equivalent with dim `D2`-->
987///
988/// <tr>
989/// <td>
990///
991/// equivalent with dim `D2` (e.g. converting from dynamic dim to const dim)
992///
993/// </td>
994/// <td colspan="5">
995///
996/// [`a.into_dimensionality::<D2>()`][.into_dimensionality()]
997///
998/// </td>
999/// </tr>
1000///
1001/// <!--Conversions to equivalent with dim `IxDyn`-->
1002///
1003/// <tr>
1004/// <td>
1005///
1006/// equivalent with dim `IxDyn`
1007///
1008/// </td>
1009/// <td colspan="5">
1010///
1011/// [`a.into_dyn()`][.into_dyn()]
1012///
1013/// </td>
1014/// </tr>
1015///
1016/// <!--Conversions to `Array<B, D>`-->
1017///
1018/// <tr>
1019/// <td>
1020///
1021/// `Array<B, D>` (new element type)
1022///
1023/// </td>
1024/// <td colspan="5">
1025///
1026/// [`a.map(|x| x.do_your_conversion())`][.map()]
1027///
1028/// </td>
1029/// </tr>
1030/// </table>
1031///
1032/// ### Conversions Between Arrays and `Vec`s/Slices/Scalars
1033///
1034/// This is a table of the safe conversions between arrays and
1035/// `Vec`s/slices/scalars. Note that some of the return values are actually
1036/// `Result`/`Option` wrappers around the indicated output types.
1037///
1038/// Input | Output | Methods
1039/// ------|--------|--------
1040/// `Vec<A>` | `ArrayBase<S: DataOwned, Ix1>` | [`::from_vec()`](Self::from_vec)
1041/// `Vec<A>` | `ArrayBase<S: DataOwned, D>` | [`::from_shape_vec()`](Self::from_shape_vec)
1042/// `&[A]` | `ArrayView1<A>` | [`::from()`](ArrayView#method.from)
1043/// `&[A]` | `ArrayView<A, D>` | [`::from_shape()`](ArrayView#method.from_shape)
1044/// `&mut [A]` | `ArrayViewMut1<A>` | [`::from()`](ArrayViewMut#method.from)
1045/// `&mut [A]` | `ArrayViewMut<A, D>` | [`::from_shape()`](ArrayViewMut#method.from_shape)
1046/// `&ArrayBase<S, Ix1>` | `Vec<A>` | [`.to_vec()`](Self::to_vec)
1047/// `Array<A, D>` | `Vec<A>` | [`.into_raw_vec()`](Array#method.into_raw_vec)<sup>[1](#into_raw_vec)</sup>
1048/// `&ArrayBase<S, D>` | `&[A]` | [`.as_slice()`](Self::as_slice)<sup>[2](#req_contig_std)</sup>, [`.as_slice_memory_order()`](Self::as_slice_memory_order)<sup>[3](#req_contig)</sup>
1049/// `&mut ArrayBase<S: DataMut, D>` | `&mut [A]` | [`.as_slice_mut()`](Self::as_slice_mut)<sup>[2](#req_contig_std)</sup>, [`.as_slice_memory_order_mut()`](Self::as_slice_memory_order_mut)<sup>[3](#req_contig)</sup>
1050/// `ArrayView<A, D>` | `&[A]` | [`.to_slice()`](ArrayView#method.to_slice)<sup>[2](#req_contig_std)</sup>
1051/// `ArrayViewMut<A, D>` | `&mut [A]` | [`.into_slice()`](ArrayViewMut#method.into_slice)<sup>[2](#req_contig_std)</sup>
1052/// `Array0<A>` | `A` | [`.into_scalar()`](Array#method.into_scalar)
1053///
1054/// <sup><a name="into_raw_vec">1</a></sup>Returns the data in memory order.
1055///
1056/// <sup><a name="req_contig_std">2</a></sup>Works only if the array is
1057/// contiguous and in standard order.
1058///
1059/// <sup><a name="req_contig">3</a></sup>Works only if the array is contiguous.
1060///
1061/// The table above does not include all the constructors; it only shows
1062/// conversions to/from `Vec`s/slices. See
1063/// [below](#constructor-methods-for-owned-arrays) for more constructors.
1064///
1065/// [ArrayView::reborrow()]: ArrayView#method.reborrow
1066/// [ArrayViewMut::reborrow()]: ArrayViewMut#method.reborrow
1067/// [.into_dimensionality()]: Self::into_dimensionality
1068/// [.into_dyn()]: Self::into_dyn
1069/// [.into_owned()]: Self::into_owned
1070/// [.into_shared()]: Self::into_shared
1071/// [.to_owned()]: Self::to_owned
1072/// [.map()]: Self::map
1073/// [.view()]: Self::view
1074/// [.view_mut()]: Self::view_mut
1075///
1076/// ### Conversions from Nested `Vec`s/`Array`s
1077///
1078/// It's generally a good idea to avoid nested `Vec`/`Array` types, such as
1079/// `Vec<Vec<A>>` or `Vec<Array2<A>>` because:
1080///
1081/// * they require extra heap allocations compared to a single `Array`,
1082///
1083/// * they can scatter data all over memory (because of multiple allocations),
1084///
1085/// * they cause unnecessary indirection (traversing multiple pointers to reach
1086///   the data),
1087///
1088/// * they don't enforce consistent shape within the nested
1089///   `Vec`s/`ArrayBase`s, and
1090///
1091/// * they are generally more difficult to work with.
1092///
1093/// The most common case where users might consider using nested
1094/// `Vec`s/`Array`s is when creating an array by appending rows/subviews in a
1095/// loop, where the rows/subviews are computed within the loop. However, there
1096/// are better ways than using nested `Vec`s/`Array`s.
1097///
1098/// If you know ahead-of-time the shape of the final array, the cleanest
1099/// solution is to allocate the final array before the loop, and then assign
1100/// the data to it within the loop, like this:
1101///
1102/// ```rust
1103/// use ndarray::{array, Array2, Axis};
1104///
1105/// let mut arr = Array2::zeros((2, 3));
1106/// for (i, mut row) in arr.axis_iter_mut(Axis(0)).enumerate() {
1107///     // Perform calculations and assign to `row`; this is a trivial example:
1108///     row.fill(i);
1109/// }
1110/// assert_eq!(arr, array![[0, 0, 0], [1, 1, 1]]);
1111/// ```
1112///
1113/// If you don't know ahead-of-time the shape of the final array, then the
1114/// cleanest solution is generally to append the data to a flat `Vec`, and then
1115/// convert it to an `Array` at the end with
1116/// [`::from_shape_vec()`](Self::from_shape_vec). You just have to be careful
1117/// that the layout of the data (the order of the elements in the flat `Vec`)
1118/// is correct.
1119///
1120/// ```rust
1121/// use ndarray::{array, Array2};
1122///
1123/// let ncols = 3;
1124/// let mut data = Vec::new();
1125/// let mut nrows = 0;
1126/// for i in 0..2 {
1127///     // Compute `row` and append it to `data`; this is a trivial example:
1128///     let row = vec![i; ncols];
1129///     data.extend_from_slice(&row);
1130///     nrows += 1;
1131/// }
1132/// let arr = Array2::from_shape_vec((nrows, ncols), data)?;
1133/// assert_eq!(arr, array![[0, 0, 0], [1, 1, 1]]);
1134/// # Ok::<(), ndarray::ShapeError>(())
1135/// ```
1136///
1137/// If neither of these options works for you, and you really need to convert
1138/// nested `Vec`/`Array` instances to an `Array`, the cleanest solution is
1139/// generally to use [`Iterator::flatten()`]
1140/// to get a flat `Vec`, and then convert the `Vec` to an `Array` with
1141/// [`::from_shape_vec()`](Self::from_shape_vec), like this:
1142///
1143/// ```rust
1144/// use ndarray::{array, Array2, Array3};
1145///
1146/// let nested: Vec<Array2<i32>> = vec![
1147///     array![[1, 2, 3], [4, 5, 6]],
1148///     array![[7, 8, 9], [10, 11, 12]],
1149/// ];
1150/// let inner_shape = nested[0].dim();
1151/// let shape = (nested.len(), inner_shape.0, inner_shape.1);
1152/// let flat: Vec<i32> = nested.iter().flatten().cloned().collect();
1153/// let arr = Array3::from_shape_vec(shape, flat)?;
1154/// assert_eq!(arr, array![
1155///     [[1, 2, 3], [4, 5, 6]],
1156///     [[7, 8, 9], [10, 11, 12]],
1157/// ]);
1158/// # Ok::<(), ndarray::ShapeError>(())
1159/// ```
1160///
1161/// Note that this implementation assumes that the nested `Vec`s are all the
1162/// same shape and that the `Vec` is non-empty. Depending on your application,
1163/// it may be a good idea to add checks for these assumptions and possibly
1164/// choose a different way to handle the empty case.
1165///
1166// # For implementors
1167//
1168// All methods must uphold the following constraints:
1169//
1170// 1. `data` must correctly represent the data buffer / ownership information,
1171//    `ptr` must point into the data represented by `data`, and the `dim` and
1172//    `strides` must be consistent with `data`. For example,
1173//
1174//    * If `data` is `OwnedRepr<A>`, all elements represented by `ptr`, `dim`,
1175//      and `strides` must be owned by the `Vec` and not aliased by multiple
1176//      indices.
1177//
1178//    * If `data` is `ViewRepr<&'a mut A>`, all elements represented by `ptr`,
1179//      `dim`, and `strides` must be exclusively borrowed and not aliased by
1180//      multiple indices.
1181//
1182// 2. If the type of `data` implements `Data`, then `ptr` must be aligned.
1183//
1184// 3. `ptr` must be non-null, and it must be safe to [`.offset()`] `ptr` by
1185//    zero.
1186//
1187// 4. It must be safe to [`.offset()`] the pointer repeatedly along all axes
1188//    and calculate the `count`s for the `.offset()` calls without overflow,
1189//    even if the array is empty or the elements are zero-sized.
1190//
1191//    More specifically, the set of all possible (signed) offset counts
1192//    relative to `ptr` can be determined by the following (the casts and
1193//    arithmetic must not overflow):
1194//
1195//    ```rust
1196//    /// Returns all the possible offset `count`s relative to `ptr`.
1197//    fn all_offset_counts(shape: &[usize], strides: &[isize]) -> BTreeSet<isize> {
1198//        assert_eq!(shape.len(), strides.len());
1199//        let mut all_offsets = BTreeSet::<isize>::new();
1200//        all_offsets.insert(0);
1201//        for axis in 0..shape.len() {
1202//            let old_offsets = all_offsets.clone();
1203//            for index in 0..shape[axis] {
1204//                assert!(index <= isize::MAX as usize);
1205//                let off = (index as isize).checked_mul(strides[axis]).unwrap();
1206//                for &old_offset in &old_offsets {
1207//                    all_offsets.insert(old_offset.checked_add(off).unwrap());
1208//                }
1209//            }
1210//        }
1211//        all_offsets
1212//    }
1213//    ```
1214//
1215//    Note that it must be safe to offset the pointer *repeatedly* along all
1216//    axes, so in addition for it being safe to offset `ptr` by each of these
1217//    counts, the difference between the least and greatest address reachable
1218//    by these offsets in units of `A` and in units of bytes must not be
1219//    greater than `isize::MAX`.
1220//
1221//    In other words,
1222//
1223//    * All possible pointers generated by moving along all axes must be in
1224//      bounds or one byte past the end of a single allocation with element
1225//      type `A`. The only exceptions are if the array is empty or the element
1226//      type is zero-sized. In these cases, `ptr` may be dangling, but it must
1227//      still be safe to [`.offset()`] the pointer along the axes.
1228//
1229//    * The offset in units of bytes between the least address and greatest
1230//      address by moving along all axes must not exceed `isize::MAX`. This
1231//      constraint prevents the computed offset, in bytes, from overflowing
1232//      `isize` regardless of the starting point due to past offsets.
1233//
1234//    * The offset in units of `A` between the least address and greatest
1235//      address by moving along all axes must not exceed `isize::MAX`. This
1236//      constraint prevents overflow when calculating the `count` parameter to
1237//      [`.offset()`] regardless of the starting point due to past offsets.
1238//
1239//    For example, if the shape is [2, 0, 3] and the strides are [3, 6, -1],
1240//    the offsets of interest relative to `ptr` are -2, -1, 0, 1, 2, 3. So,
1241//    `ptr.offset(-2)`, `ptr.offset(-1)`, …, `ptr.offset(3)` must be pointers
1242//    within a single allocation with element type `A`; `(3 - (-2)) *
1243//    size_of::<A>()` must not exceed `isize::MAX`, and `3 - (-2)` must not
1244//    exceed `isize::MAX`. Note that this is a requirement even though the
1245//    array is empty (axis 1 has length 0).
1246//
1247//    A dangling pointer can be used when creating an empty array, but this
1248//    usually means all the strides have to be zero. A dangling pointer that
1249//    can safely be offset by zero bytes can be constructed with
1250//    `::std::ptr::NonNull::<A>::dangling().as_ptr()`. (It isn't entirely clear
1251//    from the documentation that a pointer created this way is safe to
1252//    `.offset()` at all, even by zero bytes, but the implementation of
1253//    `Vec<A>` does this, so we can too. See rust-lang/rust#54857 for details.)
1254//
1255// 5. The product of non-zero axis lengths must not exceed `isize::MAX`. (This
1256//    also implies that the length of any individual axis must not exceed
1257//    `isize::MAX`, and an array can contain at most `isize::MAX` elements.)
1258//    This constraint makes various calculations easier because they don't have
1259//    to worry about overflow and axis lengths can be freely cast to `isize`.
1260//
1261// Constraints 2–5 are carefully designed such that if they're upheld for the
1262// array, they're also upheld for any subset of axes of the array as well as
1263// slices/subviews/reshapes of the array. This is important for iterators that
1264// produce subviews (and other similar cases) to be safe without extra (easy to
1265// forget) checks for zero-length axes. Constraint 1 is similarly upheld for
1266// any subset of axes and slices/subviews/reshapes, except when removing a
1267// zero-length axis (since if the other axes are non-zero-length, that would
1268// allow accessing elements that should not be possible to access).
1269//
1270// Method/function implementations can rely on these constraints being upheld.
1271// The constraints can be temporarily violated within a method/function
1272// implementation since `ArrayBase` doesn't implement `Drop` and `&mut
1273// ArrayBase` is `!UnwindSafe`, but the implementation must not call
1274// methods/functions on the array while it violates the constraints.
1275//
1276// Users of the `ndarray` crate cannot rely on these constraints because they
1277// may change in the future.
1278//
1279// [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset-1
1280pub struct ArrayBase<S, D>
1281where S: RawData
1282{
1283    /// Data buffer / ownership information. (If owned, contains the data
1284    /// buffer; if borrowed, contains the lifetime and mutability.)
1285    data: S,
1286    /// A non-null pointer into the buffer held by `data`; may point anywhere
1287    /// in its range. If `S: Data`, this pointer must be aligned.
1288    ptr: std::ptr::NonNull<S::Elem>,
1289    /// The lengths of the axes.
1290    dim: D,
1291    /// The element count stride per axis. To be parsed as `isize`.
1292    strides: D,
1293}
1294
1295/// An array where the data has shared ownership and is copy on write.
1296///
1297/// The `ArcArray<A, D>` is parameterized by `A` for the element type and `D` for
1298/// the dimensionality.
1299///
1300/// It can act as both an owner as the data as well as a shared reference (view
1301/// like).
1302/// Calling a method for mutating elements on `ArcArray`, for example
1303/// [`view_mut()`](ArrayBase::view_mut) or
1304/// [`get_mut()`](ArrayBase::get_mut), will break sharing and
1305/// require a clone of the data (if it is not uniquely held).
1306///
1307/// `ArcArray` uses atomic reference counting like `Arc`, so it is `Send` and
1308/// `Sync` (when allowed by the element type of the array too).
1309///
1310/// **[`ArrayBase`]** is used to implement both the owned
1311/// arrays and the views; see its docs for an overview of all array features.
1312///
1313/// See also:
1314///
1315/// + [Constructor Methods for Owned Arrays](ArrayBase#constructor-methods-for-owned-arrays)
1316/// + [Methods For All Array Types](ArrayBase#methods-for-all-array-types)
1317pub type ArcArray<A, D> = ArrayBase<OwnedArcRepr<A>, D>;
1318
1319/// An array that owns its data uniquely.
1320///
1321/// `Array` is the main n-dimensional array type, and it owns all its array
1322/// elements.
1323///
1324/// The `Array<A, D>` is parameterized by `A` for the element type and `D` for
1325/// the dimensionality.
1326///
1327/// **[`ArrayBase`]** is used to implement both the owned
1328/// arrays and the views; see its docs for an overview of all array features.
1329///
1330/// See also:
1331///
1332/// + [Constructor Methods for Owned Arrays](ArrayBase#constructor-methods-for-owned-arrays)
1333/// + [Methods For All Array Types](ArrayBase#methods-for-all-array-types)
1334/// + Dimensionality-specific type alises
1335///   [`Array1`],
1336///   [`Array2`],
1337///   [`Array3`], ...,
1338///   [`ArrayD`],
1339///   and so on.
1340pub type Array<A, D> = ArrayBase<OwnedRepr<A>, D>;
1341
1342/// An array with copy-on-write behavior.
1343///
1344/// An `CowArray` represents either a uniquely owned array or a view of an
1345/// array. The `'a` corresponds to the lifetime of the view variant.
1346///
1347/// This type is analogous to [`std::borrow::Cow`].
1348/// If a `CowArray` instance is the immutable view variant, then calling a
1349/// method for mutating elements in the array will cause it to be converted
1350/// into the owned variant (by cloning all the elements) before the
1351/// modification is performed.
1352///
1353/// Array views have all the methods of an array (see [`ArrayBase`]).
1354///
1355/// See also [`ArcArray`], which also provides
1356/// copy-on-write behavior but has a reference-counted pointer to the data
1357/// instead of either a view or a uniquely owned copy.
1358pub type CowArray<'a, A, D> = ArrayBase<CowRepr<'a, A>, D>;
1359
1360/// A read-only array view.
1361///
1362/// An array view represents an array or a part of it, created from
1363/// an iterator, subview or slice of an array.
1364///
1365/// The `ArrayView<'a, A, D>` is parameterized by `'a` for the scope of the
1366/// borrow, `A` for the element type and `D` for the dimensionality.
1367///
1368/// Array views have all the methods of an array (see [`ArrayBase`]).
1369///
1370/// See also [`ArrayViewMut`].
1371pub type ArrayView<'a, A, D> = ArrayBase<ViewRepr<&'a A>, D>;
1372
1373/// A read-write array view.
1374///
1375/// An array view represents an array or a part of it, created from
1376/// an iterator, subview or slice of an array.
1377///
1378/// The `ArrayViewMut<'a, A, D>` is parameterized by `'a` for the scope of the
1379/// borrow, `A` for the element type and `D` for the dimensionality.
1380///
1381/// Array views have all the methods of an array (see [`ArrayBase`]).
1382///
1383/// See also [`ArrayView`].
1384pub type ArrayViewMut<'a, A, D> = ArrayBase<ViewRepr<&'a mut A>, D>;
1385
1386/// A read-only array view without a lifetime.
1387///
1388/// This is similar to [`ArrayView`] but does not carry any lifetime or
1389/// ownership information, and its data cannot be read without an unsafe
1390/// conversion into an [`ArrayView`]. The relationship between `RawArrayView`
1391/// and [`ArrayView`] is somewhat analogous to the relationship between `*const
1392/// T` and `&T`, but `RawArrayView` has additional requirements that `*const T`
1393/// does not, such as non-nullness.
1394///
1395/// The `RawArrayView<A, D>` is parameterized by `A` for the element type and
1396/// `D` for the dimensionality.
1397///
1398/// Raw array views have all the methods of an array (see
1399/// [`ArrayBase`]).
1400///
1401/// See also [`RawArrayViewMut`].
1402///
1403/// # Warning
1404///
1405/// You can't use this type with an arbitrary raw pointer; see
1406/// [`from_shape_ptr`](#method.from_shape_ptr) for details.
1407pub type RawArrayView<A, D> = ArrayBase<RawViewRepr<*const A>, D>;
1408
1409/// A mutable array view without a lifetime.
1410///
1411/// This is similar to [`ArrayViewMut`] but does not carry any lifetime or
1412/// ownership information, and its data cannot be read/written without an
1413/// unsafe conversion into an [`ArrayViewMut`]. The relationship between
1414/// `RawArrayViewMut` and [`ArrayViewMut`] is somewhat analogous to the
1415/// relationship between `*mut T` and `&mut T`, but `RawArrayViewMut` has
1416/// additional requirements that `*mut T` does not, such as non-nullness.
1417///
1418/// The `RawArrayViewMut<A, D>` is parameterized by `A` for the element type
1419/// and `D` for the dimensionality.
1420///
1421/// Raw array views have all the methods of an array (see
1422/// [`ArrayBase`]).
1423///
1424/// See also [`RawArrayView`].
1425///
1426/// # Warning
1427///
1428/// You can't use this type with an arbitrary raw pointer; see
1429/// [`from_shape_ptr`](#method.from_shape_ptr) for details.
1430pub type RawArrayViewMut<A, D> = ArrayBase<RawViewRepr<*mut A>, D>;
1431
1432pub use data_repr::OwnedRepr;
1433
1434/// ArcArray's representation.
1435///
1436/// *Don’t use this type directly—use the type alias
1437/// [`ArcArray`] for the array type!*
1438#[derive(Debug)]
1439pub struct OwnedArcRepr<A>(Arc<OwnedRepr<A>>);
1440
1441impl<A> Clone for OwnedArcRepr<A>
1442{
1443    fn clone(&self) -> Self
1444    {
1445        OwnedArcRepr(self.0.clone())
1446    }
1447}
1448
1449/// Array pointer’s representation.
1450///
1451/// *Don’t use this type directly—use the type aliases
1452/// [`RawArrayView`] / [`RawArrayViewMut`] for the array type!*
1453#[derive(Copy, Clone)]
1454// This is just a marker type, to carry the mutability and element type.
1455pub struct RawViewRepr<A>
1456{
1457    ptr: PhantomData<A>,
1458}
1459
1460impl<A> RawViewRepr<A>
1461{
1462    #[inline(always)]
1463    const fn new() -> Self
1464    {
1465        RawViewRepr { ptr: PhantomData }
1466    }
1467}
1468
1469/// Array view’s representation.
1470///
1471/// *Don’t use this type directly—use the type aliases
1472/// [`ArrayView`] / [`ArrayViewMut`] for the array type!*
1473#[derive(Copy, Clone)]
1474// This is just a marker type, to carry the lifetime parameter.
1475pub struct ViewRepr<A>
1476{
1477    life: PhantomData<A>,
1478}
1479
1480impl<A> ViewRepr<A>
1481{
1482    #[inline(always)]
1483    const fn new() -> Self
1484    {
1485        ViewRepr { life: PhantomData }
1486    }
1487}
1488
1489/// CowArray's representation.
1490///
1491/// *Don't use this type directly—use the type alias
1492/// [`CowArray`] for the array type!*
1493pub enum CowRepr<'a, A>
1494{
1495    /// Borrowed data.
1496    View(ViewRepr<&'a A>),
1497    /// Owned data.
1498    Owned(OwnedRepr<A>),
1499}
1500
1501impl<'a, A> CowRepr<'a, A>
1502{
1503    /// Returns `true` iff the data is the `View` variant.
1504    pub fn is_view(&self) -> bool
1505    {
1506        match self {
1507            CowRepr::View(_) => true,
1508            CowRepr::Owned(_) => false,
1509        }
1510    }
1511
1512    /// Returns `true` iff the data is the `Owned` variant.
1513    pub fn is_owned(&self) -> bool
1514    {
1515        match self {
1516            CowRepr::View(_) => false,
1517            CowRepr::Owned(_) => true,
1518        }
1519    }
1520}
1521
1522// NOTE: The order of modules decides in which order methods on the type ArrayBase
1523// (mainly mentioning that as the most relevant type) show up in the documentation.
1524// Consider the doc effect of ordering modules here.
1525mod impl_clone;
1526
1527mod impl_internal_constructors;
1528mod impl_constructors;
1529
1530mod impl_methods;
1531mod impl_owned_array;
1532mod impl_special_element_types;
1533
1534/// Private Methods
1535impl<A, S, D> ArrayBase<S, D>
1536where
1537    S: Data<Elem = A>,
1538    D: Dimension,
1539{
1540    #[inline]
1541    fn broadcast_unwrap<E>(&self, dim: E) -> ArrayView<'_, A, E>
1542    where E: Dimension
1543    {
1544        #[cold]
1545        #[inline(never)]
1546        fn broadcast_panic<D, E>(from: &D, to: &E) -> !
1547        where
1548            D: Dimension,
1549            E: Dimension,
1550        {
1551            panic!(
1552                "ndarray: could not broadcast array from shape: {:?} to: {:?}",
1553                from.slice(),
1554                to.slice()
1555            )
1556        }
1557
1558        match self.broadcast(dim.clone()) {
1559            Some(it) => it,
1560            None => broadcast_panic(&self.dim, &dim),
1561        }
1562    }
1563
1564    // Broadcast to dimension `E`, without checking that the dimensions match
1565    // (Checked in debug assertions).
1566    #[inline]
1567    fn broadcast_assume<E>(&self, dim: E) -> ArrayView<'_, A, E>
1568    where E: Dimension
1569    {
1570        let dim = dim.into_dimension();
1571        debug_assert_eq!(self.shape(), dim.slice());
1572        let ptr = self.ptr;
1573        let mut strides = dim.clone();
1574        strides.slice_mut().copy_from_slice(self.strides.slice());
1575        unsafe { ArrayView::new(ptr, dim, strides) }
1576    }
1577
1578    /// Remove array axis `axis` and return the result.
1579    fn try_remove_axis(self, axis: Axis) -> ArrayBase<S, D::Smaller>
1580    {
1581        let d = self.dim.try_remove_axis(axis);
1582        let s = self.strides.try_remove_axis(axis);
1583        // safe because new dimension, strides allow access to a subset of old data
1584        unsafe { self.with_strides_dim(s, d) }
1585    }
1586}
1587
1588// parallel methods
1589#[cfg(feature = "rayon")]
1590pub mod parallel;
1591
1592mod impl_1d;
1593mod impl_2d;
1594mod impl_dyn;
1595
1596mod numeric;
1597
1598pub mod linalg;
1599
1600mod impl_ops;
1601pub use crate::impl_ops::ScalarOperand;
1602
1603#[cfg(feature = "approx")]
1604mod array_approx;
1605
1606// Array view methods
1607mod impl_views;
1608
1609// Array raw view methods
1610mod impl_raw_views;
1611
1612// Copy-on-write array methods
1613mod impl_cow;
1614
1615// Arc array methods
1616mod impl_arc_array;
1617
1618/// Returns `true` if the pointer is aligned.
1619pub(crate) fn is_aligned<T>(ptr: *const T) -> bool
1620{
1621    (ptr as usize) % ::std::mem::align_of::<T>() == 0
1622}
1623
1624// Triangular constructors
1625mod tri;
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy