ndarray/
impl_constructors.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Constructor methods for ndarray
10//!
11//!
12
13#![allow(clippy::match_wild_err_arm)]
14#[cfg(feature = "std")]
15use num_traits::Float;
16use num_traits::{One, Zero};
17use std::mem;
18use std::mem::MaybeUninit;
19use alloc::vec;
20use alloc::vec::Vec;
21
22use crate::dimension;
23use crate::dimension::offset_from_ptr_to_memory;
24use crate::error::{self, ShapeError};
25use crate::extension::nonnull::nonnull_from_vec_data;
26use crate::imp_prelude::*;
27use crate::indexes;
28use crate::indices;
29#[cfg(feature = "std")]
30use crate::iterators::to_vec;
31use crate::iterators::to_vec_mapped;
32use crate::StrideShape;
33#[cfg(feature = "std")]
34use crate::{geomspace, linspace, logspace};
35use rawpointer::PointerExt;
36
37
38/// # Constructor Methods for Owned Arrays
39///
40/// Note that the constructor methods apply to `Array` and `ArcArray`,
41/// the two array types that have owned storage.
42///
43/// ## Constructor methods for one-dimensional arrays.
44impl<S, A> ArrayBase<S, Ix1>
45where
46    S: DataOwned<Elem = A>,
47{
48    /// Create a one-dimensional array from a vector (no copying needed).
49    ///
50    /// **Panics** if the length is greater than `isize::MAX`.
51    ///
52    /// ```rust
53    /// use ndarray::Array;
54    ///
55    /// let array = Array::from_vec(vec![1., 2., 3., 4.]);
56    /// ```
57    pub fn from_vec(v: Vec<A>) -> Self {
58        if mem::size_of::<A>() == 0 {
59            assert!(
60                v.len() <= isize::MAX as usize,
61                "Length must fit in `isize`.",
62            );
63        }
64        unsafe { Self::from_shape_vec_unchecked(v.len() as Ix, v) }
65    }
66
67    /// Create a one-dimensional array from an iterator or iterable.
68    ///
69    /// **Panics** if the length is greater than `isize::MAX`.
70    ///
71    /// ```rust
72    /// use ndarray::Array;
73    ///
74    /// let array = Array::from_iter(0..10);
75    /// ```
76    #[allow(clippy::should_implement_trait)]
77    pub fn from_iter<I: IntoIterator<Item = A>>(iterable: I) -> Self {
78        Self::from_vec(iterable.into_iter().collect())
79    }
80
81    /// Create a one-dimensional array with `n` evenly spaced elements from
82    /// `start` to `end` (inclusive). `A` must be a floating point type.
83    ///
84    /// Note that if `start > end`, the first element will still be `start`,
85    /// and the following elements will be decreasing. This is different from
86    /// the behavior of `std::ops::RangeInclusive`, which interprets `start >
87    /// end` to mean that the range is empty.
88    ///
89    /// **Panics** if `n` is greater than `isize::MAX` or if converting `n - 1`
90    /// to type `A` fails.
91    ///
92    /// ```rust
93    /// use ndarray::{Array, arr1};
94    ///
95    /// let array = Array::linspace(0., 1., 5);
96    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
97    /// ```
98    #[cfg(feature = "std")]
99    pub fn linspace(start: A, end: A, n: usize) -> Self
100    where
101        A: Float,
102    {
103        Self::from(to_vec(linspace::linspace(start, end, n)))
104    }
105
106    /// Create a one-dimensional array with elements from `start` to `end`
107    /// (exclusive), incrementing by `step`. `A` must be a floating point type.
108    ///
109    /// **Panics** if the length is greater than `isize::MAX`.
110    ///
111    /// ```rust
112    /// use ndarray::{Array, arr1};
113    ///
114    /// let array = Array::range(0., 5., 1.);
115    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
116    /// ```
117    #[cfg(feature = "std")]
118    pub fn range(start: A, end: A, step: A) -> Self
119    where
120        A: Float,
121    {
122        Self::from(to_vec(linspace::range(start, end, step)))
123    }
124
125    /// Create a one-dimensional array with `n` logarithmically spaced
126    /// elements, with the starting value being `base.powf(start)` and the
127    /// final one being `base.powf(end)`. `A` must be a floating point type.
128    ///
129    /// If `base` is negative, all values will be negative.
130    ///
131    /// **Panics** if `n` is greater than `isize::MAX` or if converting `n - 1`
132    /// to type `A` fails.
133    ///
134    /// ```rust
135    /// use approx::assert_abs_diff_eq;
136    /// use ndarray::{Array, arr1};
137    ///
138    /// # #[cfg(feature = "approx")] {
139    /// let array = Array::logspace(10.0, 0.0, 3.0, 4);
140    /// assert_abs_diff_eq!(array, arr1(&[1e0, 1e1, 1e2, 1e3]));
141    ///
142    /// let array = Array::logspace(-10.0, 3.0, 0.0, 4);
143    /// assert_abs_diff_eq!(array, arr1(&[-1e3, -1e2, -1e1, -1e0]));
144    /// # }
145    /// ```
146    #[cfg(feature = "std")]
147    pub fn logspace(base: A, start: A, end: A, n: usize) -> Self
148    where
149        A: Float,
150    {
151        Self::from(to_vec(logspace::logspace(base, start, end, n)))
152    }
153
154    /// Create a one-dimensional array with `n` geometrically spaced elements
155    /// from `start` to `end` (inclusive). `A` must be a floating point type.
156    ///
157    /// Returns `None` if `start` and `end` have different signs or if either
158    /// one is zero. Conceptually, this means that in order to obtain a `Some`
159    /// result, `end / start` must be positive.
160    ///
161    /// **Panics** if `n` is greater than `isize::MAX` or if converting `n - 1`
162    /// to type `A` fails.
163    ///
164    /// ```rust
165    /// use approx::assert_abs_diff_eq;
166    /// use ndarray::{Array, arr1};
167    ///
168    /// # fn example() -> Option<()> {
169    /// # #[cfg(feature = "approx")] {
170    /// let array = Array::geomspace(1e0, 1e3, 4)?;
171    /// assert_abs_diff_eq!(array, arr1(&[1e0, 1e1, 1e2, 1e3]), epsilon = 1e-12);
172    ///
173    /// let array = Array::geomspace(-1e3, -1e0, 4)?;
174    /// assert_abs_diff_eq!(array, arr1(&[-1e3, -1e2, -1e1, -1e0]), epsilon = 1e-12);
175    /// # }
176    /// # Some(())
177    /// # }
178    /// #
179    /// # example().unwrap();
180    /// ```
181    #[cfg(feature = "std")]
182    pub fn geomspace(start: A, end: A, n: usize) -> Option<Self>
183    where
184        A: Float,
185    {
186        Some(Self::from(to_vec(geomspace::geomspace(start, end, n)?)))
187    }
188}
189
190/// ## Constructor methods for two-dimensional arrays.
191impl<S, A> ArrayBase<S, Ix2>
192where
193    S: DataOwned<Elem = A>,
194{
195    /// Create an identity matrix of size `n` (square 2D array).
196    ///
197    /// **Panics** if `n * n` would overflow `isize`.
198    pub fn eye(n: Ix) -> Self
199    where
200        S: DataMut,
201        A: Clone + Zero + One,
202    {
203        let mut eye = Self::zeros((n, n));
204        for a_ii in eye.diag_mut() {
205            *a_ii = A::one();
206        }
207        eye
208    }
209
210    /// Create a 2D matrix from its diagonal
211    ///
212    /// **Panics** if `diag.len() * diag.len()` would overflow `isize`.
213    ///
214    /// ```rust
215    /// use ndarray::{Array2, arr1, arr2};
216    ///
217    /// let diag = arr1(&[1, 2]);
218    /// let array = Array2::from_diag(&diag);
219    /// assert_eq!(array, arr2(&[[1, 0], [0, 2]]));
220    /// ```
221    pub fn from_diag<S2>(diag: &ArrayBase<S2, Ix1>) -> Self
222    where
223        A: Clone + Zero,
224        S: DataMut,
225        S2: Data<Elem = A>,
226    {
227        let n = diag.len();
228        let mut arr = Self::zeros((n, n));
229        arr.diag_mut().assign(&diag);
230        arr
231    }
232}
233
234#[cfg(not(debug_assertions))]
235#[allow(clippy::match_wild_err_arm)]
236macro_rules! size_of_shape_checked_unwrap {
237    ($dim:expr) => {
238        match dimension::size_of_shape_checked($dim) {
239            Ok(sz) => sz,
240            Err(_) => {
241                panic!("ndarray: Shape too large, product of non-zero axis lengths overflows isize")
242            }
243        }
244    };
245}
246
247#[cfg(debug_assertions)]
248macro_rules! size_of_shape_checked_unwrap {
249    ($dim:expr) => {
250        match dimension::size_of_shape_checked($dim) {
251            Ok(sz) => sz,
252            Err(_) => panic!(
253                "ndarray: Shape too large, product of non-zero axis lengths \
254                 overflows isize in shape {:?}",
255                $dim
256            ),
257        }
258    };
259}
260
261/// ## Constructor methods for n-dimensional arrays.
262///
263/// The `shape` argument can be an integer or a tuple of integers to specify
264/// a static size. For example `10` makes a length 10 one-dimensional array
265/// (dimension type `Ix1`) and `(5, 6)` a 5 × 6 array (dimension type `Ix2`).
266///
267/// With the trait `ShapeBuilder` in scope, there is the method `.f()` to select
268/// column major (“f” order) memory layout instead of the default row major.
269/// For example `Array::zeros((5, 6).f())` makes a column major 5 × 6 array.
270///
271/// Use [`IxDyn`](type.IxDyn.html) for the shape to create an array with dynamic
272/// number of axes.
273///
274/// Finally, the few constructors that take a completely general
275/// `Into<StrideShape>` argument *optionally* support custom strides, for
276/// example a shape given like `(10, 2, 2).strides((1, 10, 20))` is valid.
277impl<S, A, D> ArrayBase<S, D>
278where
279    S: DataOwned<Elem = A>,
280    D: Dimension,
281{
282    /// Create an array with copies of `elem`, shape `shape`.
283    ///
284    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
285    ///
286    /// ```
287    /// use ndarray::{Array, arr3, ShapeBuilder};
288    ///
289    /// let a = Array::from_elem((2, 2, 2), 1.);
290    ///
291    /// assert!(
292    ///     a == arr3(&[[[1., 1.],
293    ///                  [1., 1.]],
294    ///                 [[1., 1.],
295    ///                  [1., 1.]]])
296    /// );
297    /// assert!(a.strides() == &[4, 2, 1]);
298    ///
299    /// let b = Array::from_elem((2, 2, 2).f(), 1.);
300    /// assert!(b.strides() == &[1, 2, 4]);
301    /// ```
302    pub fn from_elem<Sh>(shape: Sh, elem: A) -> Self
303    where
304        A: Clone,
305        Sh: ShapeBuilder<Dim = D>,
306    {
307        let shape = shape.into_shape();
308        let size = size_of_shape_checked_unwrap!(&shape.dim);
309        let v = vec![elem; size];
310        unsafe { Self::from_shape_vec_unchecked(shape, v) }
311    }
312
313    /// Create an array with zeros, shape `shape`.
314    ///
315    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
316    pub fn zeros<Sh>(shape: Sh) -> Self
317    where
318        A: Clone + Zero,
319        Sh: ShapeBuilder<Dim = D>,
320    {
321        Self::from_elem(shape, A::zero())
322    }
323
324    /// Create an array with ones, shape `shape`.
325    ///
326    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
327    pub fn ones<Sh>(shape: Sh) -> Self
328    where
329        A: Clone + One,
330        Sh: ShapeBuilder<Dim = D>,
331    {
332        Self::from_elem(shape, A::one())
333    }
334
335    /// Create an array with default values, shape `shape`
336    ///
337    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
338    pub fn default<Sh>(shape: Sh) -> Self
339    where
340        A: Default,
341        Sh: ShapeBuilder<Dim = D>,
342    {
343        Self::from_shape_simple_fn(shape, A::default)
344    }
345
346    /// Create an array with values created by the function `f`.
347    ///
348    /// `f` is called with no argument, and it should return the element to
349    /// create. If the precise index of the element to create is needed,
350    /// use [`from_shape_fn`](ArrayBase::from_shape_fn) instead.
351    ///
352    /// This constructor can be useful if the element order is not important,
353    /// for example if they are identical or random.
354    ///
355    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
356    pub fn from_shape_simple_fn<Sh, F>(shape: Sh, mut f: F) -> Self
357    where
358        Sh: ShapeBuilder<Dim = D>,
359        F: FnMut() -> A,
360    {
361        let shape = shape.into_shape();
362        let len = size_of_shape_checked_unwrap!(&shape.dim);
363        let v = to_vec_mapped(0..len, move |_| f());
364        unsafe { Self::from_shape_vec_unchecked(shape, v) }
365    }
366
367    /// Create an array with values created by the function `f`.
368    ///
369    /// `f` is called with the index of the element to create; the elements are
370    /// visited in arbitrary order.
371    ///
372    /// **Panics** if the product of non-zero axis lengths overflows `isize`.
373    ///
374    /// ```
375    /// use ndarray::{Array, arr2};
376    ///
377    /// // Create a table of i × j (with i and j from 1 to 3)
378    /// let ij_table = Array::from_shape_fn((3, 3), |(i, j)| (1 + i) * (1 + j));
379    ///
380    /// assert_eq!(
381    ///     ij_table,
382    ///     arr2(&[[1, 2, 3],
383    ///            [2, 4, 6],
384    ///            [3, 6, 9]])
385    /// );
386    /// ```
387    pub fn from_shape_fn<Sh, F>(shape: Sh, f: F) -> Self
388    where
389        Sh: ShapeBuilder<Dim = D>,
390        F: FnMut(D::Pattern) -> A,
391    {
392        let shape = shape.into_shape();
393        let _ = size_of_shape_checked_unwrap!(&shape.dim);
394        if shape.is_c() {
395            let v = to_vec_mapped(indices(shape.dim.clone()).into_iter(), f);
396            unsafe { Self::from_shape_vec_unchecked(shape, v) }
397        } else {
398            let dim = shape.dim.clone();
399            let v = to_vec_mapped(indexes::indices_iter_f(dim), f);
400            unsafe { Self::from_shape_vec_unchecked(shape, v) }
401        }
402    }
403
404    /// Create an array with the given shape from a vector. (No cloning of
405    /// elements needed.)
406    ///
407    /// ----
408    ///
409    /// For a contiguous c- or f-order shape, the following applies:
410    ///
411    /// **Errors** if `shape` does not correspond to the number of elements in
412    /// `v` or if the shape/strides would result in overflowing `isize`.
413    ///
414    /// ----
415    ///
416    /// For custom strides, the following applies:
417    ///
418    /// **Errors** if strides and dimensions can point out of bounds of `v`, if
419    /// strides allow multiple indices to point to the same element, or if the
420    /// shape/strides would result in overflowing `isize`.
421    ///
422    /// ```
423    /// use ndarray::Array;
424    /// use ndarray::ShapeBuilder; // Needed for .strides() method
425    /// use ndarray::arr2;
426    ///
427    /// let a = Array::from_shape_vec((2, 2), vec![1., 2., 3., 4.]);
428    /// assert!(a.is_ok());
429    ///
430    /// let b = Array::from_shape_vec((2, 2).strides((1, 2)),
431    ///                               vec![1., 2., 3., 4.]).unwrap();
432    /// assert!(
433    ///     b == arr2(&[[1., 3.],
434    ///                 [2., 4.]])
435    /// );
436    /// ```
437    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<Self, ShapeError>
438    where
439        Sh: Into<StrideShape<D>>,
440    {
441        // eliminate the type parameter Sh as soon as possible
442        Self::from_shape_vec_impl(shape.into(), v)
443    }
444
445    fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec<A>) -> Result<Self, ShapeError> {
446        let dim = shape.dim;
447        let is_custom = shape.strides.is_custom();
448        dimension::can_index_slice_with_strides(&v, &dim, &shape.strides)?;
449        if !is_custom && dim.size() != v.len() {
450            return Err(error::incompatible_shapes(&Ix1(v.len()), &dim));
451        }
452        let strides = shape.strides.strides_for_dim(&dim);
453        unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
454    }
455
456    /// Creates an array from a vector and interpret it according to the
457    /// provided shape and strides. (No cloning of elements needed.)
458    ///
459    /// # Safety
460    ///
461    /// The caller must ensure that the following conditions are met:
462    ///
463    /// 1. The ndim of `dim` and `strides` must be the same.
464    ///
465    /// 2. The product of non-zero axis lengths must not exceed `isize::MAX`.
466    ///
467    /// 3. For axes with length > 1, the pointer cannot move outside the
468    ///    slice.
469    ///
470    /// 4. If the array will be empty (any axes are zero-length), the
471    ///    difference between the least address and greatest address accessible
472    ///    by moving along all axes must be ≤ `v.len()`.
473    ///
474    ///    If the array will not be empty, the difference between the least
475    ///    address and greatest address accessible by moving along all axes
476    ///    must be < `v.len()`.
477    ///
478    /// 5. The strides must not allow any element to be referenced by two different
479    ///    indices.
480    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> Self
481    where
482        Sh: Into<StrideShape<D>>,
483    {
484        let shape = shape.into();
485        let dim = shape.dim;
486        let strides = shape.strides.strides_for_dim(&dim);
487        Self::from_vec_dim_stride_unchecked(dim, strides, v)
488    }
489
490    unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>) -> Self {
491        // debug check for issues that indicates wrong use of this constructor
492        debug_assert!(dimension::can_index_slice(&v, &dim, &strides).is_ok());
493
494        let ptr = nonnull_from_vec_data(&mut v).offset(-offset_from_ptr_to_memory(&dim, &strides));
495        ArrayBase::from_data_ptr(DataOwned::new(v), ptr).with_strides_dim(strides, dim)
496    }
497
498    /// Create an array with uninitalized elements, shape `shape`.
499    ///
500    /// The uninitialized elements of type `A` are represented by the type `MaybeUninit<A>`,
501    /// an easier way to handle uninit values correctly.
502    ///
503    /// Only *when* the array is completely initialized with valid elements, can it be
504    /// converted to an array of `A` elements using [`.assume_init()`].
505    ///
506    /// **Panics** if the number of elements in `shape` would overflow isize.
507    ///
508    /// ### Safety
509    ///
510    /// The whole of the array must be initialized before it is converted
511    /// using [`.assume_init()`] or otherwise traversed.
512    ///
513    /// ### Examples
514    ///
515    /// It is possible to assign individual values through `*elt = MaybeUninit::new(value)`
516    /// and so on.
517    ///
518    /// [`.assume_init()`]: ArrayBase::assume_init
519    ///
520    /// ```
521    /// use ndarray::{s, Array2};
522    /// use ndarray::Zip;
523    /// use ndarray::Axis;
524    ///
525    /// // Example Task: Let's create a column shifted copy of the input
526    ///
527    /// fn shift_by_two(a: &Array2<f32>) -> Array2<f32> {
528    ///     // create an uninitialized array
529    ///     let mut b = Array2::uninit(a.dim());
530    ///
531    ///     // two first columns in b are two last in a
532    ///     // rest of columns in b are the initial columns in a
533    ///
534    ///     a.slice(s![.., -2..]).assign_to(b.slice_mut(s![.., ..2]));
535    ///     a.slice(s![.., 2..]).assign_to(b.slice_mut(s![.., ..-2]));
536    ///
537    ///     // Now we can promise that `b` is safe to use with all operations
538    ///     unsafe {
539    ///         b.assume_init()
540    ///     }
541    /// }
542    /// ```
543    pub fn uninit<Sh>(shape: Sh) -> ArrayBase<S::MaybeUninit, D>
544    where
545        Sh: ShapeBuilder<Dim = D>,
546    {
547        unsafe {
548            let shape = shape.into_shape();
549            let size = size_of_shape_checked_unwrap!(&shape.dim);
550            let mut v = Vec::with_capacity(size);
551            v.set_len(size);
552            ArrayBase::from_shape_vec_unchecked(shape, v)
553        }
554    }
555
556    /// Create an array with uninitalized elements, shape `shape`.
557    ///
558    /// The uninitialized elements of type `A` are represented by the type `MaybeUninit<A>`,
559    /// an easier way to handle uninit values correctly.
560    ///
561    /// The `builder` closure gets unshared access to the array through a raw view
562    /// and can use it to modify the array before it is returned. This allows initializing
563    /// the array for any owned array type (avoiding clone requirements for copy-on-write,
564    /// because the array is unshared when initially created).
565    ///
566    /// Only *when* the array is completely initialized with valid elements, can it be
567    /// converted to an array of `A` elements using [`.assume_init()`].
568    ///
569    /// **Panics** if the number of elements in `shape` would overflow isize.
570    ///
571    /// ### Safety
572    ///
573    /// The whole of the array must be initialized before it is converted
574    /// using [`.assume_init()`] or otherwise traversed.
575    ///
576    pub(crate) fn build_uninit<Sh, F>(shape: Sh, builder: F) -> ArrayBase<S::MaybeUninit, D>
577    where
578        Sh: ShapeBuilder<Dim = D>,
579        F: FnOnce(RawArrayViewMut<MaybeUninit<A>, D>),
580    {
581        let mut array = Self::uninit(shape);
582        // Safe because: the array is unshared here
583        unsafe {
584            builder(array.raw_view_mut_unchecked());
585        }
586        array
587    }
588
589    #[deprecated(note = "This method is hard to use correctly. Use `uninit` instead.",
590                 since = "0.15.0")]
591    /// Create an array with uninitalized elements, shape `shape`.
592    ///
593    /// Prefer to use [`uninit()`](ArrayBase::uninit) if possible, because it is
594    /// easier to use correctly.
595    ///
596    /// **Panics** if the number of elements in `shape` would overflow isize.
597    ///
598    /// ### Safety
599    ///
600    /// Accessing uninitalized values is undefined behaviour. You must overwrite *all* the elements
601    /// in the array after it is created; for example using
602    /// [`raw_view_mut`](ArrayBase::raw_view_mut) or other low-level element access.
603    ///
604    /// The contents of the array is indeterminate before initialization and it
605    /// is an error to perform operations that use the previous values. For
606    /// example it would not be legal to use `a += 1.;` on such an array.
607    ///
608    /// This constructor is limited to elements where `A: Copy` (no destructors)
609    /// to avoid users shooting themselves too hard in the foot.
610    ///
611    /// (Also note that the constructors `from_shape_vec` and
612    /// `from_shape_vec_unchecked` allow the user yet more control, in the sense
613    /// that Arrays can be created from arbitrary vectors.)
614    pub unsafe fn uninitialized<Sh>(shape: Sh) -> Self
615    where
616        A: Copy,
617        Sh: ShapeBuilder<Dim = D>,
618    {
619        let shape = shape.into_shape();
620        let size = size_of_shape_checked_unwrap!(&shape.dim);
621        let mut v = Vec::with_capacity(size);
622        v.set_len(size);
623        Self::from_shape_vec_unchecked(shape, v)
624    }
625
626}
627
628impl<S, A, D> ArrayBase<S, D>
629where
630    S: DataOwned<Elem = MaybeUninit<A>>,
631    D: Dimension,
632{
633    /// Create an array with uninitalized elements, shape `shape`.
634    ///
635    /// This method has been renamed to `uninit`
636    #[deprecated(note = "Renamed to `uninit`", since = "0.15.0")]
637    pub fn maybe_uninit<Sh>(shape: Sh) -> Self
638    where
639        Sh: ShapeBuilder<Dim = D>,
640    {
641        unsafe {
642            let shape = shape.into_shape();
643            let size = size_of_shape_checked_unwrap!(&shape.dim);
644            let mut v = Vec::with_capacity(size);
645            v.set_len(size);
646            Self::from_shape_vec_unchecked(shape, v)
647        }
648    }
649}