|
| 1 | + |
| 2 | +use std::slice; |
| 3 | + |
| 4 | +use libnum; |
| 5 | +use imp_prelude::*; |
| 6 | + |
| 7 | +/// ***Deprecated: Use `ArrayBase::zeros` instead.*** |
| 8 | +/// |
| 9 | +/// Return an array filled with zeros |
| 10 | +#[cfg_attr(has_deprecated, deprecated(note="Use `ArrayBase::zeros` instead."))] |
| 11 | +pub fn zeros<A, D>(dim: D) -> OwnedArray<A, D> |
| 12 | + where A: Clone + libnum::Zero, D: Dimension, |
| 13 | +{ |
| 14 | + ArrayBase::zeros(dim) |
| 15 | +} |
| 16 | + |
| 17 | +/// Return a zero-dimensional array with the element `x`. |
| 18 | +pub fn arr0<A>(x: A) -> OwnedArray<A, ()> |
| 19 | +{ |
| 20 | + unsafe { ArrayBase::from_vec_dim_unchecked((), vec![x]) } |
| 21 | +} |
| 22 | + |
| 23 | +/// Return a one-dimensional array with elements from `xs`. |
| 24 | +pub fn arr1<A: Clone>(xs: &[A]) -> OwnedArray<A, Ix> { |
| 25 | + ArrayBase::from_vec(xs.to_vec()) |
| 26 | +} |
| 27 | + |
| 28 | +/// Return a one-dimensional array with elements from `xs`. |
| 29 | +pub fn rcarr1<A: Clone>(xs: &[A]) -> RcArray<A, Ix> { |
| 30 | + arr1(xs).into_shared() |
| 31 | +} |
| 32 | + |
| 33 | +/// Return a zero-dimensional array view borrowing `x`. |
| 34 | +pub fn aview0<A>(x: &A) -> ArrayView<A, ()> { |
| 35 | + unsafe { ArrayView::new_(x, (), ()) } |
| 36 | +} |
| 37 | + |
| 38 | +/// Return a one-dimensional array view with elements borrowing `xs`. |
| 39 | +/// |
| 40 | +/// ``` |
| 41 | +/// use ndarray::aview1; |
| 42 | +/// |
| 43 | +/// let data = [1.0; 1024]; |
| 44 | +/// |
| 45 | +/// // Create a 2D array view from borrowed data |
| 46 | +/// let a2d = aview1(&data).into_shape((32, 32)).unwrap(); |
| 47 | +/// |
| 48 | +/// assert!( |
| 49 | +/// a2d.scalar_sum() == 1024.0 |
| 50 | +/// ); |
| 51 | +/// ``` |
| 52 | +pub fn aview1<A>(xs: &[A]) -> ArrayView<A, Ix> { |
| 53 | + ArrayView::from_slice(xs) |
| 54 | +} |
| 55 | + |
| 56 | +/// Return a two-dimensional array view with elements borrowing `xs`. |
| 57 | +pub fn aview2<A, V: FixedInitializer<Elem=A>>(xs: &[V]) -> ArrayView<A, (Ix, Ix)> { |
| 58 | + let cols = V::len(); |
| 59 | + let rows = xs.len(); |
| 60 | + let data = unsafe { |
| 61 | + slice::from_raw_parts(xs.as_ptr() as *const A, cols * rows) |
| 62 | + }; |
| 63 | + let dim = (rows as Ix, cols as Ix); |
| 64 | + unsafe { |
| 65 | + let strides = dim.default_strides(); |
| 66 | + ArrayView::new_(data.as_ptr(), dim, strides) |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +/// Return a one-dimensional read-write array view with elements borrowing `xs`. |
| 71 | +/// |
| 72 | +/// ``` |
| 73 | +/// #[macro_use(s)] |
| 74 | +/// extern crate ndarray; |
| 75 | +/// |
| 76 | +/// use ndarray::aview_mut1; |
| 77 | +/// |
| 78 | +/// // Create an array view over some data, then slice it and modify it. |
| 79 | +/// fn main() { |
| 80 | +/// let mut data = [0; 1024]; |
| 81 | +/// { |
| 82 | +/// let mut a = aview_mut1(&mut data).into_shape((32, 32)).unwrap(); |
| 83 | +/// a.slice_mut(s![.., ..;3]).assign_scalar(&5); |
| 84 | +/// } |
| 85 | +/// assert_eq!(&data[..10], [5, 0, 0, 5, 0, 0, 5, 0, 0, 5]); |
| 86 | +/// } |
| 87 | +/// ``` |
| 88 | +pub fn aview_mut1<A>(xs: &mut [A]) -> ArrayViewMut<A, Ix> { |
| 89 | + ArrayViewMut::from_slice(xs) |
| 90 | +} |
| 91 | + |
| 92 | +/// Fixed-size array used for array initialization |
| 93 | +pub unsafe trait FixedInitializer { |
| 94 | + type Elem; |
| 95 | + fn as_init_slice(&self) -> &[Self::Elem]; |
| 96 | + fn len() -> usize; |
| 97 | +} |
| 98 | + |
| 99 | +macro_rules! impl_arr_init { |
| 100 | + (__impl $n: expr) => ( |
| 101 | + unsafe impl<T> FixedInitializer for [T; $n] { |
| 102 | + type Elem = T; |
| 103 | + fn as_init_slice(&self) -> &[T] { self } |
| 104 | + fn len() -> usize { $n } |
| 105 | + } |
| 106 | + ); |
| 107 | + () => (); |
| 108 | + ($n: expr, $($m:expr,)*) => ( |
| 109 | + impl_arr_init!(__impl $n); |
| 110 | + impl_arr_init!($($m,)*); |
| 111 | + ) |
| 112 | + |
| 113 | +} |
| 114 | + |
| 115 | +impl_arr_init!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,); |
| 116 | + |
| 117 | +/// Return a two-dimensional array with elements from `xs`. |
| 118 | +/// |
| 119 | +/// ``` |
| 120 | +/// use ndarray::arr2; |
| 121 | +/// |
| 122 | +/// let a = arr2(&[[1, 2, 3], |
| 123 | +/// [4, 5, 6]]); |
| 124 | +/// assert!( |
| 125 | +/// a.shape() == [2, 3] |
| 126 | +/// ); |
| 127 | +/// ``` |
| 128 | +pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> OwnedArray<A, (Ix, Ix)> { |
| 129 | + // FIXME: Simplify this when V is fix size array |
| 130 | + let (m, n) = (xs.len() as Ix, |
| 131 | + xs.get(0).map_or(0, |snd| snd.as_init_slice().len() as Ix)); |
| 132 | + let dim = (m, n); |
| 133 | + let mut result = Vec::<A>::with_capacity(dim.size()); |
| 134 | + for snd in xs { |
| 135 | + let snd = snd.as_init_slice(); |
| 136 | + result.extend(snd.iter().cloned()); |
| 137 | + } |
| 138 | + unsafe { |
| 139 | + ArrayBase::from_vec_dim_unchecked(dim, result) |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +/// Return a two-dimensional array with elements from `xs`. |
| 144 | +/// |
| 145 | +pub fn rcarr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> RcArray<A, (Ix, Ix)> { |
| 146 | + arr2(xs).into_shared() |
| 147 | +} |
| 148 | + |
| 149 | +/// Return a three-dimensional array with elements from `xs`. |
| 150 | +/// |
| 151 | +/// **Panics** if the slices are not all of the same length. |
| 152 | +/// |
| 153 | +/// ``` |
| 154 | +/// use ndarray::arr3; |
| 155 | +/// |
| 156 | +/// let a = arr3(&[[[1, 2], |
| 157 | +/// [3, 4]], |
| 158 | +/// [[5, 6], |
| 159 | +/// [7, 8]], |
| 160 | +/// [[9, 0], |
| 161 | +/// [1, 2]]]); |
| 162 | +/// assert!( |
| 163 | +/// a.shape() == [3, 2, 2] |
| 164 | +/// ); |
| 165 | +/// ``` |
| 166 | +pub fn arr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V]) |
| 167 | + -> OwnedArray<A, (Ix, Ix, Ix)> |
| 168 | +{ |
| 169 | + // FIXME: Simplify this when U/V are fix size arrays |
| 170 | + let m = xs.len() as Ix; |
| 171 | + let fst = xs.get(0).map(|snd| snd.as_init_slice()); |
| 172 | + let thr = fst.and_then(|elt| elt.get(0).map(|elt2| elt2.as_init_slice())); |
| 173 | + let n = fst.map_or(0, |v| v.len() as Ix); |
| 174 | + let o = thr.map_or(0, |v| v.len() as Ix); |
| 175 | + let dim = (m, n, o); |
| 176 | + let mut result = Vec::<A>::with_capacity(dim.size()); |
| 177 | + for snd in xs { |
| 178 | + let snd = snd.as_init_slice(); |
| 179 | + for thr in snd.iter() { |
| 180 | + let thr = thr.as_init_slice(); |
| 181 | + result.extend(thr.iter().cloned()); |
| 182 | + } |
| 183 | + } |
| 184 | + unsafe { |
| 185 | + ArrayBase::from_vec_dim_unchecked(dim, result) |
| 186 | + } |
| 187 | +} |
| 188 | + |
| 189 | +/// Return a three-dimensional array with elements from `xs`. |
| 190 | +pub fn rcarr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V]) |
| 191 | + -> RcArray<A, (Ix, Ix, Ix)> |
| 192 | +{ |
| 193 | + arr3(xs).into_shared() |
| 194 | +} |
0 commit comments