Skip to content

Commit a7138e9

Browse files
committed
Merge pull request #191 from bluss/shapebuilder
Unify array with shape construction using Shape & ShapeBuilder
2 parents d918950 + b123a5e commit a7138e9

File tree

12 files changed

+325
-139
lines changed

12 files changed

+325
-139
lines changed

src/data_traits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ unsafe impl<A> DataMut for Rc<Vec<A>>
8383
// Create a new vec if the current view is less than half of
8484
// backing data.
8585
unsafe {
86-
*self_ = ArrayBase::from_vec_dim_unchecked(self_.dim.clone(),
87-
self_.iter()
86+
*self_ = ArrayBase::from_shape_vec_unchecked(self_.dim.clone(),
87+
self_.iter()
8888
.cloned()
8989
.collect());
9090
}

src/free_functions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use imp_prelude::*;
1313
/// Create a zero-dimensional array with the element `x`.
1414
pub fn arr0<A>(x: A) -> OwnedArray<A, ()>
1515
{
16-
unsafe { ArrayBase::from_vec_dim_unchecked((), vec![x]) }
16+
unsafe { ArrayBase::from_shape_vec_unchecked((), vec![x]) }
1717
}
1818

1919
/// Create a one-dimensional array with elements from `xs`.
@@ -129,7 +129,7 @@ pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> OwnedArray<A,
129129
result.extend_from_slice(snd.as_init_slice());
130130
}
131131
unsafe {
132-
ArrayBase::from_vec_dim_unchecked(dim, result)
132+
ArrayBase::from_shape_vec_unchecked(dim, result)
133133
}
134134
}
135135

@@ -167,7 +167,7 @@ pub fn arr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(
167167
}
168168
}
169169
unsafe {
170-
ArrayBase::from_vec_dim_unchecked(dim, result)
170+
ArrayBase::from_shape_vec_unchecked(dim, result)
171171
}
172172
}
173173

src/impl_constructors.rs

Lines changed: 103 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88

99
//! Constructor methods for ndarray
1010
//!
11-
use libnum;
11+
//!
12+
13+
#![allow(deprecated)] // from_shape_vec
14+
15+
use libnum::{Zero, One, Float};
1216

1317
use imp_prelude::*;
18+
use {Shape, StrideShape};
1419
use dimension;
1520
use linspace;
1621
use error::{self, ShapeError, ErrorKind};
@@ -30,7 +35,7 @@ impl<S> ArrayBase<S, Ix>
3035
/// let array = OwnedArray::from_vec(vec![1., 2., 3., 4.]);
3136
/// ```
3237
pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
33-
unsafe { Self::from_vec_dim_unchecked(v.len() as Ix, v) }
38+
unsafe { Self::from_shape_vec_unchecked(v.len() as Ix, v) }
3439
}
3540

3641
/// Create a one-dimensional array from an iterable.
@@ -58,7 +63,7 @@ impl<S> ArrayBase<S, Ix>
5863
/// ```
5964
pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
6065
where S: Data<Elem=F>,
61-
F: libnum::Float,
66+
F: Float,
6267
{
6368
Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
6469
}
@@ -74,7 +79,7 @@ impl<S> ArrayBase<S, Ix>
7479
/// ```
7580
pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
7681
where S: Data<Elem=F>,
77-
F: libnum::Float,
82+
F: Float,
7883
{
7984
Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
8085
}
@@ -89,7 +94,7 @@ impl<S, A> ArrayBase<S, (Ix, Ix)>
8994
/// **Panics** if `n * n` would overflow usize.
9095
pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
9196
where S: DataMut,
92-
A: Clone + libnum::Zero + libnum::One,
97+
A: Clone + Zero + One,
9398
{
9499
let mut eye = Self::zeros((n, n));
95100
for a_ii in eye.diag_mut() {
@@ -113,13 +118,12 @@ impl<S, A, D> ArrayBase<S, D>
113118
where S: DataOwned<Elem=A>,
114119
D: Dimension,
115120
{
116-
/// Create an array with copies of `elem`, dimension `dim`.
121+
/// Create an array with copies of `elem`, shape `shape`.
117122
///
118-
/// **Panics** if the number of elements in `dim` would overflow usize.
123+
/// **Panics** if the number of elements in `shape` would overflow usize.
119124
///
120125
/// ```
121-
/// use ndarray::OwnedArray;
122-
/// use ndarray::arr3;
126+
/// use ndarray::{OwnedArray, arr3, ShapeBuilder};
123127
///
124128
/// let a = OwnedArray::from_elem((2, 2, 2), 1.);
125129
///
@@ -130,89 +134,128 @@ impl<S, A, D> ArrayBase<S, D>
130134
/// [1., 1.]]])
131135
/// );
132136
/// assert!(a.strides() == &[4, 2, 1]);
137+
///
138+
/// let b = OwnedArray::from_elem((2, 2, 2).f(), 1.);
139+
/// assert!(b.strides() == &[1, 2, 4]);
133140
/// ```
134-
pub fn from_elem(dim: D, elem: A) -> ArrayBase<S, D>
135-
where A: Clone
141+
pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
142+
where A: Clone,
143+
Sh: Into<Shape<D>>,
136144
{
137145
// Note: We don't need to check the case of a size between
138146
// isize::MAX -> usize::MAX; in this case, the vec constructor itself
139147
// panics.
140-
let size = size_checked_unwrap!(dim);
148+
let shape = shape.into();
149+
let size = size_checked_unwrap!(shape.dim);
141150
let v = vec![elem; size];
142-
unsafe { Self::from_vec_dim_unchecked(dim, v) }
151+
unsafe { Self::from_shape_vec_unchecked(shape, v) }
143152
}
144153

145-
/// Create an array with copies of `elem`, dimension `dim` and fortran
146-
/// memory order.
147-
///
148-
/// **Panics** if the number of elements would overflow usize.
154+
/// Create an array with zeros, shape `shape`.
149155
///
150-
/// ```
151-
/// use ndarray::OwnedArray;
152-
///
153-
/// let a = OwnedArray::from_elem_f((2, 2, 2), 1.);
154-
/// assert!(a.strides() == &[1, 2, 4]);
155-
/// ```
156-
pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
157-
where A: Clone
156+
/// **Panics** if the number of elements in `shape` would overflow usize.
157+
pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
158+
where A: Clone + Zero,
159+
Sh: Into<Shape<D>>,
158160
{
159-
let size = size_checked_unwrap!(dim);
160-
let v = vec![elem; size];
161-
unsafe { Self::from_vec_dim_unchecked_f(dim, v) }
161+
Self::from_elem(shape, A::zero())
162162
}
163163

164-
/// Create an array with zeros, dimension `dim`.
164+
/// Create an array with default values, shape `shape`
165165
///
166-
/// **Panics** if the number of elements in `dim` would overflow usize.
167-
pub fn zeros(dim: D) -> ArrayBase<S, D>
168-
where A: Clone + libnum::Zero
166+
/// **Panics** if the number of elements in `shape` would overflow usize.
167+
pub fn default<Sh>(shape: Sh) -> ArrayBase<S, D>
168+
where A: Default,
169+
Sh: Into<Shape<D>>,
169170
{
170-
Self::from_elem(dim, libnum::zero())
171+
let shape = shape.into();
172+
let v = (0..shape.dim.size()).map(|_| A::default()).collect();
173+
unsafe { Self::from_shape_vec_unchecked(shape, v) }
171174
}
172175

173-
/// Create an array with zeros, dimension `dim` and fortran memory order.
176+
/// Create an array with the given shape from a vector. (No cloning of
177+
/// elements needed.)
174178
///
175-
/// **Panics** if the number of elements in `dim` would overflow usize.
176-
pub fn zeros_f(dim: D) -> ArrayBase<S, D>
177-
where A: Clone + libnum::Zero
179+
/// ----
180+
///
181+
/// For a contiguous c- or f-order shape, the following applies:
182+
///
183+
/// **Errors** if `shape` does not correspond to the number of elements in `v`.
184+
///
185+
/// ----
186+
///
187+
/// For custom strides, the following applies:
188+
///
189+
/// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
190+
/// **Errors** if strides allow multiple indices to point to the same element.
191+
pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
192+
where Sh: Into<StrideShape<D>>,
178193
{
179-
Self::from_elem_f(dim, libnum::zero())
194+
// eliminate the type parameter Sh as soon as possible
195+
Self::from_shape_vec_impl(shape.into(), v)
180196
}
181197

182-
/// Create an array with default values, dimension `dim`.
183-
///
184-
/// **Panics** if the number of elements in `dim` would overflow usize.
185-
pub fn default(dim: D) -> ArrayBase<S, D>
186-
where A: Default
198+
fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
187199
{
188-
let v = (0..dim.size()).map(|_| A::default()).collect();
189-
unsafe { Self::from_vec_dim_unchecked(dim, v) }
200+
if shape.custom {
201+
Self::from_vec_dim_stride(shape.dim, shape.strides, v)
202+
} else {
203+
let dim = shape.dim;
204+
let strides = shape.strides;
205+
if dim.size_checked() != Some(v.len()) {
206+
return Err(error::incompatible_shapes(&v.len(), &dim));
207+
}
208+
unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
209+
}
190210
}
191211

192-
/// Create an array from a vector (no copying needed).
212+
/// Create an array from a vector and interpret it according to the
213+
/// provided dimensions and strides. (No cloning of elements needed.)
193214
///
194-
/// **Errors** if `dim` does not correspond to the number of elements in `v`.
215+
/// Unsafe because dimension and strides are unchecked.
216+
pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> ArrayBase<S, D>
217+
where Sh: Into<StrideShape<D>>,
218+
{
219+
let shape = shape.into();
220+
Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
221+
}
222+
223+
#[cfg_attr(has_deprecated, deprecated(note="Use from_elem instead."))]
224+
/// ***Deprecated: Use from_elem instead***
225+
pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
226+
where A: Clone
227+
{
228+
Self::from_elem(dim.f(), elem)
229+
}
230+
231+
#[cfg_attr(has_deprecated, deprecated(note="Use zeros instead."))]
232+
/// ***Deprecated: Use zeros instead***
233+
pub fn zeros_f(dim: D) -> ArrayBase<S, D>
234+
where A: Clone + Zero
235+
{
236+
Self::from_elem_f(dim, A::zero())
237+
}
238+
239+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
240+
/// ***Deprecated: Use from_shape_vec instead***
195241
pub fn from_vec_dim(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
196242
if dim.size_checked() != Some(v.len()) {
197243
return Err(error::incompatible_shapes(&v.len(), &dim));
198244
}
199245
unsafe { Ok(Self::from_vec_dim_unchecked(dim, v)) }
200246
}
201247

202-
/// Create an array from a vector (no copying needed) using fortran
203-
/// memory order to interpret the data.
204-
///
205-
/// **Errors** if `dim` does not correspond to the number of elements in `v`.
248+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
249+
/// ***Deprecated: Use from_shape_vec instead***
206250
pub fn from_vec_dim_f(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
207251
if dim.size_checked() != Some(v.len()) {
208252
return Err(error::incompatible_shapes(&v.len(), &dim));
209253
}
210254
unsafe { Ok(Self::from_vec_dim_unchecked_f(dim, v)) }
211255
}
212256

213-
/// Create an array from a vector (no copying needed).
214-
///
215-
/// Unsafe because dimension is unchecked, and must be correct.
257+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
258+
/// ***Deprecated: Use from_shape_vec_unchecked instead***
216259
pub unsafe fn from_vec_dim_unchecked(dim: D, mut v: Vec<A>) -> ArrayBase<S, D> {
217260
debug_assert!(dim.size_checked() == Some(v.len()));
218261
ArrayBase {
@@ -223,24 +266,16 @@ impl<S, A, D> ArrayBase<S, D>
223266
}
224267
}
225268

226-
/// Create an array from a vector (with no copying needed),
227-
/// using fortran memory order to interpret the data.
228-
///
229-
/// Unsafe because dimension is unchecked, and must be correct.
269+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
270+
/// ***Deprecated: Use from_shape_vec_unchecked instead***
230271
pub unsafe fn from_vec_dim_unchecked_f(dim: D, v: Vec<A>) -> ArrayBase<S, D> {
231272
debug_assert!(dim.size_checked() == Some(v.len()));
232273
let strides = dim.fortran_strides();
233274
Self::from_vec_dim_stride_unchecked(dim, strides, v)
234275
}
235276

236-
/// Create an array from a vector and interpret it according to the
237-
/// provided dimensions and strides. No allocation needed.
238-
///
239-
/// Checks whether `dim` and `strides` are compatible with the vector's
240-
/// length, returning an `Err` if not compatible.
241-
///
242-
/// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
243-
/// **Errors** if strides allow multiple indices to point to the same element.
277+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
278+
/// ***Deprecated: Use from_shape_vec instead***
244279
pub fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
245280
-> Result<ArrayBase<S, D>, ShapeError>
246281
{
@@ -251,10 +286,9 @@ impl<S, A, D> ArrayBase<S, D>
251286
})
252287
}
253288

254-
/// Create an array from a vector and interpret it according to the
255-
/// provided dimensions and strides. No allocation needed.
289+
#[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
290+
/// ***Deprecated: Use from_shape_vec_unchecked instead***
256291
///
257-
/// Unsafe because dimension and strides are unchecked.
258292
pub unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
259293
-> ArrayBase<S, D>
260294
{

src/impl_methods.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
9191
(self.iter().cloned().collect(), self.dim.default_strides())
9292
};
9393
unsafe {
94-
ArrayBase::from_vec_dim_stride_unchecked(self.dim.clone(), strides, data)
94+
ArrayBase::from_shape_vec_unchecked(self.dim.clone().strides(strides), data)
9595
}
9696
}
9797

@@ -427,7 +427,7 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
427427
let mut dim = self.dim();
428428
dim.set_axis(axis, 0);
429429
unsafe {
430-
OwnedArray::from_vec_dim_unchecked(dim, vec![])
430+
OwnedArray::from_shape_vec_unchecked(dim, vec![])
431431
}
432432
} else {
433433
stack(axis, &subs).unwrap()
@@ -800,7 +800,7 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
800800
} else {
801801
let v = self.iter().map(|x| x.clone()).collect::<Vec<A>>();
802802
unsafe {
803-
ArrayBase::from_vec_dim_unchecked(shape, v)
803+
ArrayBase::from_shape_vec_unchecked(shape, v)
804804
}
805805
}
806806
}
@@ -1150,13 +1150,13 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
11501150
if let Some(slc) = self.as_slice_memory_order() {
11511151
let v = ::iterators::to_vec(slc.iter().map(f));
11521152
unsafe {
1153-
ArrayBase::from_vec_dim_stride_unchecked(
1154-
self.dim.clone(), self.strides.clone(), v)
1153+
ArrayBase::from_shape_vec_unchecked(
1154+
self.dim.clone().strides(self.strides.clone()), v)
11551155
}
11561156
} else {
11571157
let v = ::iterators::to_vec(self.iter().map(f));
11581158
unsafe {
1159-
ArrayBase::from_vec_dim_unchecked(self.dim.clone(), v)
1159+
ArrayBase::from_shape_vec_unchecked(self.dim.clone(), v)
11601160
}
11611161
}
11621162
}

0 commit comments

Comments
 (0)