Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/arraytraits.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2014-2016 bluss and ndarray developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
use std::hash;
10
use std::iter::FromIterator;
11
use std::iter::IntoIterator;
12
use std::mem;
13
use std::ops::{Index, IndexMut};
14
use alloc::boxed::Box;
15
use alloc::vec::Vec;
16
17
use crate::imp_prelude::*;
18
use crate::iter::{Iter, IterMut};
19
use crate::NdIndex;
20
21
use crate::numeric_util;
22
use crate::{FoldWhile, Zip};
23
24
#[cold]
25
#[inline(never)]
26
0
pub(crate) fn array_out_of_bounds() -> ! {
27
0
    panic!("ndarray: index out of bounds");
28
}
29
30
#[inline(always)]
31
0
pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
32
0
where
33
0
    D: Dimension,
34
0
    I: NdIndex<D>,
35
0
    S: Data,
36
0
{
37
0
    debug_bounds_check!(_a, *_index);
38
0
}
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 1]>, usize>
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<ndarray::data_repr::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>, usize>
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<ndarray::data_repr::OwnedRepr<i32>, ndarray::dimension::dim::Dim<[usize; 1]>, usize>
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<ndarray::data_repr::OwnedRepr<i16>, ndarray::dimension::dim::Dim<[usize; 1]>, usize>
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<ndarray::data_repr::OwnedRepr<i64>, ndarray::dimension::dim::Dim<[usize; 1]>, usize>
Unexecuted instantiation: ndarray::arraytraits::debug_bounds_check::<_, _, _>
39
40
/// Access the element at **index**.
41
///
42
/// **Panics** if index is out of bounds.
43
impl<S, D, I> Index<I> for ArrayBase<S, D>
44
where
45
    D: Dimension,
46
    I: NdIndex<D>,
47
    S: Data,
48
{
49
    type Output = S::Elem;
50
    #[inline]
51
0
    fn index(&self, index: I) -> &S::Elem {
52
0
        debug_bounds_check!(self, index);
53
0
        unsafe {
54
0
            &*self.ptr.as_ptr().offset(
55
0
                index
56
0
                    .index_checked(&self.dim, &self.strides)
57
0
                    .unwrap_or_else(|| array_out_of_bounds()),
58
0
            )
59
0
        }
60
0
    }
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>> as core::ops::index::Index<[usize; 0]>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&f32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&f32>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>> as core::ops::index::Index<[usize; 0]>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i32>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>> as core::ops::index::Index<[usize; 0]>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i16>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i16>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>> as core::ops::index::Index<[usize; 0]>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&i64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>> as core::ops::index::Index<[usize; 0]>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f64, noisy_float::checkers::NumChecker>>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f32, noisy_float::checkers::NumChecker>>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<i8>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<u8>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<i32>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<u32>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<i128>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<u128>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<i16>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<u16>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<i64>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut core::option::Option<u64>>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut f64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::ViewRepr<&mut f32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::ops::index::Index<usize>>::index
Unexecuted instantiation: <ndarray::ArrayBase<_, _> as core::ops::index::Index<_>>::index
61
}
62
63
/// Access the element at **index** mutably.
64
///
65
/// **Panics** if index is out of bounds.
66
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
67
where
68
    D: Dimension,
69
    I: NdIndex<D>,
70
    S: DataMut,
71
{
72
    #[inline]
73
0
    fn index_mut(&mut self, index: I) -> &mut S::Elem {
74
0
        debug_bounds_check!(self, index);
75
0
        unsafe {
76
0
            &mut *self.as_mut_ptr().offset(
77
0
                index
78
0
                    .index_checked(&self.dim, &self.strides)
79
0
                    .unwrap_or_else(|| array_out_of_bounds()),
80
0
            )
81
0
        }
82
0
    }
83
}
84
85
/// Return `true` if the array shapes and all elements of `self` and
86
/// `rhs` are equal. Return `false` otherwise.
87
impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
88
where
89
    A: PartialEq<B>,
90
    S: Data<Elem = A>,
91
    S2: Data<Elem = B>,
92
    D: Dimension,
93
{
94
0
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
95
0
        if self.shape() != rhs.shape() {
96
0
            return false;
97
0
        }
98
0
        if let Some(self_s) = self.as_slice() {
99
0
            if let Some(rhs_s) = rhs.as_slice() {
100
0
                return numeric_util::unrolled_eq(self_s, rhs_s);
101
0
            }
102
0
        }
103
0
        Zip::from(self)
104
0
            .and(rhs)
105
0
            .fold_while(true, |_, a, b| {
106
0
                if a != b {
107
0
                    FoldWhile::Done(false)
108
                } else {
109
0
                    FoldWhile::Continue(true)
110
                }
111
0
            })
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq::{closure#0}
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq::{closure#0}
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq::{closure#0}
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i16>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq::{closure#0}
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq::{closure#0}
Unexecuted instantiation: <ndarray::ArrayBase<_, _> as core::cmp::PartialEq<ndarray::ArrayBase<_, _>>>::eq::{closure#0}
112
0
            .into_inner()
113
0
    }
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i32>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i16>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<i64>, ndarray::dimension::dim::Dim<[usize; 1]>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <ndarray::ArrayBase<_, _> as core::cmp::PartialEq<ndarray::ArrayBase<_, _>>>::eq
114
}
115
116
/// Return `true` if the array shapes and all elements of `self` and
117
/// `rhs` are equal. Return `false` otherwise.
118
impl<'a, A, B, S, S2, D> PartialEq<&'a ArrayBase<S2, D>> for ArrayBase<S, D>
119
where
120
    A: PartialEq<B>,
121
    S: Data<Elem = A>,
122
    S2: Data<Elem = B>,
123
    D: Dimension,
124
{
125
0
    fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool {
126
0
        *self == **rhs
127
0
    }
128
}
129
130
/// Return `true` if the array shapes and all elements of `self` and
131
/// `rhs` are equal. Return `false` otherwise.
132
impl<'a, A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &'a ArrayBase<S, D>
133
where
134
    A: PartialEq<B>,
135
    S: Data<Elem = A>,
136
    S2: Data<Elem = B>,
137
    D: Dimension,
138
{
139
0
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
140
0
        **self == *rhs
141
0
    }
142
}
143
144
impl<S, D> Eq for ArrayBase<S, D>
145
where
146
    D: Dimension,
147
    S: Data,
148
    S::Elem: Eq,
149
{
150
}
151
152
impl<A, S> From<Box<[A]>> for ArrayBase<S, Ix1>
153
where
154
    S: DataOwned<Elem = A>,
155
{
156
    /// Create a one-dimensional array from a boxed slice (no copying needed).
157
    ///
158
    /// **Panics** if the length is greater than `isize::MAX`.
159
0
    fn from(b: Box<[A]>) -> Self {
160
0
        Self::from_vec(b.into_vec())
161
0
    }
162
}
163
164
impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
165
where
166
    S: DataOwned<Elem = A>,
167
{
168
    /// Create a one-dimensional array from a vector (no copying needed).
169
    ///
170
    /// **Panics** if the length is greater than `isize::MAX`.
171
    ///
172
    /// ```rust
173
    /// use ndarray::Array;
174
    ///
175
    /// let array = Array::from(vec![1., 2., 3., 4.]);
176
    /// ```
177
0
    fn from(v: Vec<A>) -> Self {
178
0
        Self::from_vec(v)
179
0
    }
180
}
181
182
impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
183
where
184
    S: DataOwned<Elem = A>,
185
{
186
    /// Create a one-dimensional array from an iterable.
187
    ///
188
    /// **Panics** if the length is greater than `isize::MAX`.
189
    ///
190
    /// ```rust
191
    /// use ndarray::{Array, arr1};
192
    ///
193
    /// // Either use `from_iter` directly or use `Iterator::collect`.
194
    /// let array = Array::from_iter((0..5).map(|x| x * x));
195
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
196
    /// ```
197
0
    fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
198
0
    where
199
0
        I: IntoIterator<Item = A>,
200
0
    {
201
0
        Self::from_iter(iterable)
202
0
    }
203
}
204
205
impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
206
where
207
    D: Dimension,
208
    S: Data,
209
{
210
    type Item = &'a S::Elem;
211
    type IntoIter = Iter<'a, S::Elem, D>;
212
213
0
    fn into_iter(self) -> Self::IntoIter {
214
0
        self.iter()
215
0
    }
216
}
217
218
impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
219
where
220
    D: Dimension,
221
    S: DataMut,
222
{
223
    type Item = &'a mut S::Elem;
224
    type IntoIter = IterMut<'a, S::Elem, D>;
225
226
0
    fn into_iter(self) -> Self::IntoIter {
227
0
        self.iter_mut()
228
0
    }
229
}
230
231
impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
232
where
233
    D: Dimension,
234
{
235
    type Item = &'a A;
236
    type IntoIter = Iter<'a, A, D>;
237
238
0
    fn into_iter(self) -> Self::IntoIter {
239
0
        self.into_iter_()
240
0
    }
241
}
242
243
impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
244
where
245
    D: Dimension,
246
{
247
    type Item = &'a mut A;
248
    type IntoIter = IterMut<'a, A, D>;
249
250
0
    fn into_iter(self) -> Self::IntoIter {
251
0
        self.into_iter_()
252
0
    }
253
}
254
255
impl<S, D> hash::Hash for ArrayBase<S, D>
256
where
257
    D: Dimension,
258
    S: Data,
259
    S::Elem: hash::Hash,
260
{
261
    // Note: elements are hashed in the logical order
262
0
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
263
0
        self.shape().hash(state);
264
0
        if let Some(self_s) = self.as_slice() {
265
0
            hash::Hash::hash_slice(self_s, state);
266
0
        } else {
267
0
            for row in self.rows() {
268
0
                if let Some(row_s) = row.as_slice() {
269
0
                    hash::Hash::hash_slice(row_s, state);
270
0
                } else {
271
0
                    for elt in row {
272
0
                        elt.hash(state)
273
                    }
274
                }
275
            }
276
        }
277
0
    }
278
}
279
280
// NOTE: ArrayBase keeps an internal raw pointer that always
281
// points into the storage. This is Sync & Send as long as we
282
// follow the usual inherited mutability rules, as we do with
283
// Vec, &[] and &mut []
284
285
/// `ArrayBase` is `Sync` when the storage type is.
286
unsafe impl<S, D> Sync for ArrayBase<S, D>
287
where
288
    S: Sync + Data,
289
    D: Sync,
290
{
291
}
292
293
/// `ArrayBase` is `Send` when the storage type is.
294
unsafe impl<S, D> Send for ArrayBase<S, D>
295
where
296
    S: Send + Data,
297
    D: Send,
298
{
299
}
300
301
#[cfg(any(feature = "serde"))]
302
// Use version number so we can add a packed format later.
303
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
304
305
// use "raw" form instead of type aliases here so that they show up in docs
306
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or sliceable.
307
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
308
where
309
    Slice: AsRef<[A]>,
310
{
311
    /// Create a one-dimensional read-only array view of the data in `slice`.
312
    ///
313
    /// **Panics** if the slice length is greater than `isize::MAX`.
314
0
    fn from(slice: &'a Slice) -> Self {
315
0
        let xs = slice.as_ref();
316
0
        if mem::size_of::<A>() == 0 {
317
0
            assert!(
318
0
                xs.len() <= ::std::isize::MAX as usize,
319
0
                "Slice length must fit in `isize`.",
320
0
            );
321
0
        }
322
0
        unsafe { Self::from_shape_ptr(xs.len(), xs.as_ptr()) }
323
0
    }
324
}
325
326
/// Implementation of `ArrayView::from(&A)` where `A` is an array.
327
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
328
where
329
    S: Data<Elem = A>,
330
    D: Dimension,
331
{
332
    /// Create a read-only array view of the array.
333
0
    fn from(array: &'a ArrayBase<S, D>) -> Self {
334
0
        array.view()
335
0
    }
336
}
337
338
/// Implementation of `ArrayViewMut::from(&mut S)` where `S` is a slice or sliceable.
339
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
340
where
341
    Slice: AsMut<[A]>,
342
{
343
    /// Create a one-dimensional read-write array view of the data in `slice`.
344
    ///
345
    /// **Panics** if the slice length is greater than `isize::MAX`.
346
0
    fn from(slice: &'a mut Slice) -> Self {
347
0
        let xs = slice.as_mut();
348
0
        if mem::size_of::<A>() == 0 {
349
0
            assert!(
350
0
                xs.len() <= ::std::isize::MAX as usize,
351
0
                "Slice length must fit in `isize`.",
352
0
            );
353
0
        }
354
0
        unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
355
0
    }
356
}
357
358
/// Implementation of `ArrayViewMut::from(&mut A)` where `A` is an array.
359
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
360
where
361
    S: DataMut<Elem = A>,
362
    D: Dimension,
363
{
364
    /// Create a read-write array view of the array.
365
0
    fn from(array: &'a mut ArrayBase<S, D>) -> Self {
366
0
        array.view_mut()
367
0
    }
368
}
369
370
impl<A, D> From<Array<A, D>> for ArcArray<A, D>
371
where
372
    D: Dimension,
373
{
374
0
    fn from(arr: Array<A, D>) -> ArcArray<A, D> {
375
0
        arr.into_shared()
376
0
    }
377
}
378
379
/// Argument conversion into an array view
380
///
381
/// The trait is parameterized over `A`, the element type, and `D`, the
382
/// dimensionality of the array. `D` defaults to one-dimensional.
383
///
384
/// Use `.into()` to do the conversion.
385
///
386
/// ```
387
/// use ndarray::AsArray;
388
///
389
/// fn sum<'a, V: AsArray<'a, f64>>(data: V) -> f64 {
390
///     let array_view = data.into();
391
///     array_view.sum()
392
/// }
393
///
394
/// assert_eq!(
395
///     sum(&[1., 2., 3.]),
396
///     6.
397
/// );
398
///
399
/// ```
400
pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
401
where
402
    D: Dimension,
403
{
404
}
405
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
406
where
407
    T: Into<ArrayView<'a, A, D>>,
408
    D: Dimension,
409
{
410
}
411
412
/// Create an owned array with a default state.
413
///
414
/// The array is created with dimension `D::default()`, which results
415
/// in for example dimensions `0` and `(0, 0)` with zero elements for the
416
/// one-dimensional and two-dimensional cases respectively.
417
///
418
/// The default dimension for `IxDyn` is `IxDyn(&[0])` (array has zero
419
/// elements). And the default for the dimension `()` is `()` (array has
420
/// one element).
421
///
422
/// Since arrays cannot grow, the intention is to use the default value as
423
/// placeholder.
424
impl<A, S, D> Default for ArrayBase<S, D>
425
where
426
    S: DataOwned<Elem = A>,
427
    D: Dimension,
428
    A: Default,
429
{
430
    // NOTE: We can implement Default for non-zero dimensional array views by
431
    // using an empty slice, however we need a trait for nonzero Dimension.
432
0
    fn default() -> Self {
433
0
        ArrayBase::default(D::default())
434
0
    }
435
}