Coverage Report

Created: 2026-03-11 07:34

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