Thanks to visit codestin.com
Credit goes to docs.rs

ndarray/
free_functions.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use alloc::vec;
10#[cfg(not(feature = "std"))]
11use alloc::vec::Vec;
12#[allow(unused_imports)]
13use std::compile_error;
14use std::mem::{forget, size_of};
15use std::ptr::NonNull;
16
17use crate::imp_prelude::*;
18use crate::{dimension, ArcArray1, ArcArray2};
19
20/// Create an **[`Array`]** with one, two, three, four, five, or six dimensions.
21///
22/// ```
23/// use ndarray::array;
24/// let a1 = array![1, 2, 3, 4];
25///
26/// let a2 = array![[1, 2],
27///                 [3, 4]];
28///
29/// let a3 = array![[[1, 2], [3, 4]],
30///                 [[5, 6], [7, 8]]];
31///
32/// let a4 = array![[[[1, 2, 3, 4]]]];
33///
34/// let a5 = array![[[[[1, 2, 3, 4, 5]]]]];
35///
36/// let a6 = array![[[[[[1, 2, 3, 4, 5, 6]]]]]];
37///
38/// assert_eq!(a1.shape(), &[4]);
39/// assert_eq!(a2.shape(), &[2, 2]);
40/// assert_eq!(a3.shape(), &[2, 2, 2]);
41/// assert_eq!(a4.shape(), &[1, 1, 1, 4]);
42/// assert_eq!(a5.shape(), &[1, 1, 1, 1, 5]);
43/// assert_eq!(a6.shape(), &[1, 1, 1, 1, 1, 6]);
44/// ```
45///
46/// This macro uses `vec![]`, and has the same ownership semantics;
47/// elements are moved into the resulting `Array`.
48///
49/// Use `array![...].into_shared()` to create an `ArcArray`.
50///
51/// Attempts to crate 7D+ arrays with this macro will lead to
52/// a compiler error, since the difference between a 7D array
53/// of i32 and a 6D array of `[i32; 3]` is ambiguous. Higher-dim
54/// arrays can be created with [`ArrayD`].
55///
56/// ```compile_fail
57/// use ndarray::array;
58/// let a7 = array![[[[[[[1, 2, 3]]]]]]];
59/// // error: Arrays of 7 dimensions or more (or ndarrays of Rust arrays) cannot be constructed with the array! macro.
60/// ```
61#[macro_export]
62macro_rules! array {
63    ($([$([$([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
64        compile_error!("Arrays of 7 dimensions or more (or ndarrays of Rust arrays) cannot be constructed with the array! macro.");
65    }};
66    ($([$([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
67        $crate::Array6::from(vec![$([$([$([$([$([$($x,)*],)*],)*],)*],)*],)*])
68    }};
69    ($([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
70        $crate::Array5::from(vec![$([$([$([$([$($x,)*],)*],)*],)*],)*])
71    }};
72    ($([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
73        $crate::Array4::from(vec![$([$([$([$($x,)*],)*],)*],)*])
74    }};
75    ($([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*) => {{
76        $crate::Array3::from(vec![$([$([$($x,)*],)*],)*])
77    }};
78    ($([$($x:expr),* $(,)*]),+ $(,)*) => {{
79        $crate::Array2::from(vec![$([$($x,)*],)*])
80    }};
81    ($($x:expr),* $(,)*) => {{
82        $crate::Array::from(vec![$($x,)*])
83    }};
84}
85
86/// Create a zero-dimensional array with the element `x`.
87pub fn arr0<A>(x: A) -> Array0<A>
88{
89    unsafe { ArrayBase::from_shape_vec_unchecked((), vec![x]) }
90}
91
92/// Create a one-dimensional array with elements from `xs`.
93pub fn arr1<A: Clone>(xs: &[A]) -> Array1<A>
94{
95    ArrayBase::from(xs.to_vec())
96}
97
98/// Create a one-dimensional array with elements from `xs`.
99pub fn rcarr1<A: Clone>(xs: &[A]) -> ArcArray1<A>
100{
101    arr1(xs).into_shared()
102}
103
104/// Create a zero-dimensional array view borrowing `x`.
105pub const fn aview0<A>(x: &A) -> ArrayView0<'_, A>
106{
107    ArrayBase {
108        data: ViewRepr::new(),
109        // Safe because references are always non-null.
110        ptr: unsafe { NonNull::new_unchecked(x as *const A as *mut A) },
111        dim: Ix0(),
112        strides: Ix0(),
113    }
114}
115
116/// Create a one-dimensional array view with elements borrowing `xs`.
117///
118/// **Panics** if the length of the slice overflows `isize`. (This can only
119/// occur if `A` is zero-sized, because slices cannot contain more than
120/// `isize::MAX` number of bytes.)
121///
122/// ```
123/// use ndarray::{aview1, ArrayView1};
124///
125/// let data = [1.0; 1024];
126///
127/// // Create a 2D array view from borrowed data
128/// let a2d = aview1(&data).into_shape_with_order((32, 32)).unwrap();
129///
130/// assert_eq!(a2d.sum(), 1024.0);
131///
132/// // Create a const 1D array view
133/// const C: ArrayView1<'static, f64> = aview1(&[1., 2., 3.]);
134///
135/// assert_eq!(C.sum(), 6.);
136/// ```
137pub const fn aview1<A>(xs: &[A]) -> ArrayView1<'_, A>
138{
139    if size_of::<A>() == 0 {
140        assert!(
141            xs.len() <= isize::MAX as usize,
142            "Slice length must fit in `isize`.",
143        );
144    }
145    ArrayBase {
146        data: ViewRepr::new(),
147        // Safe because references are always non-null.
148        ptr: unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) },
149        dim: Ix1(xs.len()),
150        strides: Ix1(1),
151    }
152}
153
154/// Create a two-dimensional array view with elements borrowing `xs`.
155///
156/// **Panics** if the product of non-zero axis lengths overflows `isize` (This
157/// can only occur if A is zero-sized or if `N` is zero, because slices cannot
158/// contain more than `isize::MAX` number of bytes).
159///
160/// ```
161/// use ndarray::{aview2, ArrayView2};
162///
163/// let data = vec![[1., 2., 3.], [4., 5., 6.]];
164///
165/// let view = aview2(&data);
166/// assert_eq!(view.sum(), 21.);
167///
168/// // Create a const 2D array view
169/// const C: ArrayView2<'static, f64> = aview2(&[[1., 2., 3.], [4., 5., 6.]]);
170/// assert_eq!(C.sum(), 21.);
171/// ```
172pub const fn aview2<A, const N: usize>(xs: &[[A; N]]) -> ArrayView2<'_, A>
173{
174    let cols = N;
175    let rows = xs.len();
176    if size_of::<A>() == 0 {
177        if let Some(n_elems) = rows.checked_mul(cols) {
178            assert!(
179                rows <= isize::MAX as usize
180                    && cols <= isize::MAX as usize
181                    && n_elems <= isize::MAX as usize,
182                "Product of non-zero axis lengths must not overflow isize.",
183            );
184        } else {
185            panic!("Overflow in number of elements.");
186        }
187    } else if N == 0 {
188        assert!(
189            rows <= isize::MAX as usize,
190            "Product of non-zero axis lengths must not overflow isize.",
191        );
192    }
193    // Safe because references are always non-null.
194    let ptr = unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) };
195    let dim = Ix2(rows, cols);
196    let strides = if rows == 0 || cols == 0 {
197        Ix2(0, 0)
198    } else {
199        Ix2(cols, 1)
200    };
201    ArrayBase {
202        data: ViewRepr::new(),
203        ptr,
204        dim,
205        strides,
206    }
207}
208
209/// Create a one-dimensional read-write array view with elements borrowing `xs`.
210///
211/// ```
212/// use ndarray::{aview_mut1, s};
213/// // Create an array view over some data, then slice it and modify it.
214/// let mut data = [0; 1024];
215/// {
216///     let mut a = aview_mut1(&mut data).into_shape_with_order((32, 32)).unwrap();
217///     a.slice_mut(s![.., ..;3]).fill(5);
218/// }
219/// assert_eq!(&data[..10], [5, 0, 0, 5, 0, 0, 5, 0, 0, 5]);
220/// ```
221pub fn aview_mut1<A>(xs: &mut [A]) -> ArrayViewMut1<'_, A>
222{
223    ArrayViewMut::from(xs)
224}
225
226/// Create a two-dimensional read-write array view with elements borrowing `xs`.
227///
228/// **Panics** if the product of non-zero axis lengths overflows `isize` (This can only occur if A
229/// is zero-sized because slices cannot contain more than `isize::MAX` number of bytes).
230///
231/// # Example
232///
233/// ```
234/// use ndarray::aview_mut2;
235///
236/// // The inner (nested) and outer arrays can be of any length.
237/// let mut data = [[0.; 2]; 128];
238/// {
239///     // Make a 128 x 2 mut array view then turn it into 2 x 128
240///     let mut a = aview_mut2(&mut data).reversed_axes();
241///     // Make the first row ones and second row minus ones.
242///     a.row_mut(0).fill(1.);
243///     a.row_mut(1).fill(-1.);
244/// }
245/// // look at the start of the result
246/// assert_eq!(&data[..3], [[1., -1.], [1., -1.], [1., -1.]]);
247/// ```
248pub fn aview_mut2<A, const N: usize>(xs: &mut [[A; N]]) -> ArrayViewMut2<'_, A>
249{
250    ArrayViewMut2::from(xs)
251}
252
253/// Create a two-dimensional array with elements from `xs`.
254///
255/// ```
256/// use ndarray::arr2;
257///
258/// let a = arr2(&[[1, 2, 3],
259///                [4, 5, 6]]);
260/// assert!(
261///     a.shape() == [2, 3]
262/// );
263/// ```
264pub fn arr2<A: Clone, const N: usize>(xs: &[[A; N]]) -> Array2<A>
265{
266    Array2::from(xs.to_vec())
267}
268
269macro_rules! impl_from_nested_vec {
270    ($arr_type:ty, $ix_type:tt, $($n:ident),+) => {
271        impl<A, $(const $n: usize),+> From<Vec<$arr_type>> for Array<A, $ix_type>
272        {
273            fn from(mut xs: Vec<$arr_type>) -> Self
274            {
275                let dim = $ix_type(xs.len(), $($n),+);
276                let ptr = xs.as_mut_ptr();
277                let cap = xs.capacity();
278                let expand_len = dimension::size_of_shape_checked(&dim)
279                    .expect("Product of non-zero axis lengths must not overflow isize.");
280                forget(xs);
281                unsafe {
282                    let v = if size_of::<A>() == 0 {
283                        Vec::from_raw_parts(ptr as *mut A, expand_len, expand_len)
284                    } else if $($n == 0 ||)+ false {
285                        Vec::new()
286                    } else {
287                        let expand_cap = cap $(* $n)+;
288                        Vec::from_raw_parts(ptr as *mut A, expand_len, expand_cap)
289                    };
290                    ArrayBase::from_shape_vec_unchecked(dim, v)
291                }
292            }
293        }
294    };
295}
296
297impl_from_nested_vec!([A; N], Ix2, N);
298impl_from_nested_vec!([[A; M]; N], Ix3, N, M);
299impl_from_nested_vec!([[[A; L]; M]; N], Ix4, N, M, L);
300impl_from_nested_vec!([[[[A; K]; L]; M]; N], Ix5, N, M, L, K);
301impl_from_nested_vec!([[[[[A; J]; K]; L]; M]; N], Ix6, N, M, L, K, J);
302
303/// Create a two-dimensional array with elements from `xs`.
304///
305pub fn rcarr2<A: Clone, const N: usize>(xs: &[[A; N]]) -> ArcArray2<A>
306{
307    arr2(xs).into_shared()
308}
309
310/// Create a three-dimensional array with elements from `xs`.
311///
312/// **Panics** if the slices are not all of the same length.
313///
314/// ```
315/// use ndarray::arr3;
316///
317/// let a = arr3(&[[[1, 2],
318///                 [3, 4]],
319///                [[5, 6],
320///                 [7, 8]],
321///                [[9, 0],
322///                 [1, 2]]]);
323/// assert!(
324///     a.shape() == [3, 2, 2]
325/// );
326/// ```
327pub fn arr3<A: Clone, const N: usize, const M: usize>(xs: &[[[A; M]; N]]) -> Array3<A>
328{
329    Array3::from(xs.to_vec())
330}
331
332/// Create a three-dimensional array with elements from `xs`.
333pub fn rcarr3<A: Clone, const N: usize, const M: usize>(xs: &[[[A; M]; N]]) -> ArcArray<A, Ix3>
334{
335    arr3(xs).into_shared()
336}