@@ -99,15 +99,15 @@ impl<A> Array<A, Ix2> {
9999 ///
100100 /// // create an empty array and append
101101 /// let mut a = Array::zeros((0, 4));
102- /// a.append_row (ArrayView::from(&[ 1., 2., 3., 4.])).unwrap();
103- /// a.append_row (ArrayView::from(&[-1., -2., -3., -4.])).unwrap();
102+ /// a.push_row (ArrayView::from(&[ 1., 2., 3., 4.])).unwrap();
103+ /// a.push_row (ArrayView::from(&[-1., -2., -3., -4.])).unwrap();
104104 ///
105105 /// assert_eq!(
106106 /// a,
107107 /// array![[ 1., 2., 3., 4.],
108108 /// [-1., -2., -3., -4.]]);
109109 /// ```
110- pub fn append_row ( & mut self , row : ArrayView < A , Ix1 > ) -> Result < ( ) , ShapeError >
110+ pub fn push_row ( & mut self , row : ArrayView < A , Ix1 > ) -> Result < ( ) , ShapeError >
111111 where
112112 A : Clone ,
113113 {
@@ -136,15 +136,15 @@ impl<A> Array<A, Ix2> {
136136 ///
137137 /// // create an empty array and append
138138 /// let mut a = Array::zeros((2, 0));
139- /// a.append_column (ArrayView::from(&[1., 2.])).unwrap();
140- /// a.append_column (ArrayView::from(&[-1., -2.])).unwrap();
139+ /// a.push_column (ArrayView::from(&[1., 2.])).unwrap();
140+ /// a.push_column (ArrayView::from(&[-1., -2.])).unwrap();
141141 ///
142142 /// assert_eq!(
143143 /// a,
144144 /// array![[1., -1.],
145145 /// [2., -2.]]);
146146 /// ```
147- pub fn append_column ( & mut self , column : ArrayView < A , Ix1 > ) -> Result < ( ) , ShapeError >
147+ pub fn push_column ( & mut self , column : ArrayView < A , Ix1 > ) -> Result < ( ) , ShapeError >
148148 where
149149 A : Clone ,
150150 {
@@ -278,8 +278,66 @@ impl<A, D> Array<A, D>
278278 }
279279 }
280280
281+ /// Append an array to the array along an axis
282+ ///
283+ /// Where the item to push to the array has one dimension less than the `self` array. This
284+ /// method is equivalent to `self.append(axis, array.insert_axis(axis))`.
285+ ///
286+ /// The axis-to-append-to `axis` must be the array's "growing axis" for this operation
287+ /// to succeed. The growing axis is the outermost or last-visited when elements are visited in
288+ /// memory order:
289+ ///
290+ /// `axis` must be the growing axis of the current array, an axis with length 0 or 1.
291+ ///
292+ /// - This is the 0th axis for standard layout arrays
293+ /// - This is the *n*-1 th axis for fortran layout arrays
294+ /// - If the array is empty (the axis or any other has length 0) or if `axis`
295+ /// has length 1, then the array can always be appended.
296+ ///
297+ /// ***Errors*** with a shape error if the shape of self does not match the array-to-append;
298+ /// all axes *except* the axis along which it being appended matter for this check.
299+ ///
300+ /// The memory layout of the `self` array matters for ensuring that the append is efficient.
301+ /// Appending automatically changes memory layout of the array so that it is appended to
302+ /// along the "growing axis".
303+ ///
304+ /// Ensure appending is efficient by for example starting from an empty array and/or always
305+ /// appending to an array along the same axis.
306+ ///
307+ /// The amortized average complexity of the append, when appending along its growing axis, is
308+ /// O(*m*) where *m* is the length of the row.
309+ ///
310+ /// The memory layout of the argument `array` does not matter to the same extent.
311+ ///
312+ /// ```rust
313+ /// use ndarray::{Array, ArrayView, array, Axis};
314+ ///
315+ /// // create an empty array and push rows to it
316+ /// let mut a = Array::zeros((0, 4));
317+ /// let ones = ArrayView::from(&[1.; 4]);
318+ /// let zeros = ArrayView::from(&[0.; 4]);
319+ /// a.push(Axis(0), ones).unwrap();
320+ /// a.push(Axis(0), zeros).unwrap();
321+ /// a.push(Axis(0), ones).unwrap();
322+ ///
323+ /// assert_eq!(
324+ /// a,
325+ /// array![[1., 1., 1., 1.],
326+ /// [0., 0., 0., 0.],
327+ /// [1., 1., 1., 1.]]);
328+ /// ```
329+ pub fn push ( & mut self , axis : Axis , array : ArrayView < A , D :: Smaller > )
330+ -> Result < ( ) , ShapeError >
331+ where
332+ A : Clone ,
333+ D : RemoveAxis ,
334+ {
335+ // same-dimensionality conversion
336+ self . append ( axis, array. insert_axis ( axis) . into_dimensionality :: < D > ( ) . unwrap ( ) )
337+ }
338+
281339
282- /// Append an array to the array
340+ /// Append an array to the array along an axis
283341 ///
284342 /// The axis-to-append-to `axis` must be the array's "growing axis" for this operation
285343 /// to succeed. The growing axis is the outermost or last-visited when elements are visited in
@@ -338,18 +396,19 @@ impl<A, D> Array<A, D>
338396 }
339397
340398 let current_axis_len = self . len_of ( axis) ;
341- let remaining_shape = self . raw_dim ( ) . remove_axis ( axis) ;
342- let array_rem_shape = array. raw_dim ( ) . remove_axis ( axis) ;
399+ let self_dim = self . raw_dim ( ) ;
400+ let array_dim = array. raw_dim ( ) ;
401+ let remaining_shape = self_dim. remove_axis ( axis) ;
402+ let array_rem_shape = array_dim. remove_axis ( axis) ;
343403
344404 if remaining_shape != array_rem_shape {
345405 return Err ( ShapeError :: from_kind ( ErrorKind :: IncompatibleShape ) ) ;
346406 }
347407
348408 let len_to_append = array. len ( ) ;
349409
350- let array_shape = array. raw_dim ( ) ;
351- let mut res_dim = self . raw_dim ( ) ;
352- res_dim[ axis. index ( ) ] += array_shape[ axis. index ( ) ] ;
410+ let mut res_dim = self_dim;
411+ res_dim[ axis. index ( ) ] += array_dim[ axis. index ( ) ] ;
353412 let new_len = dimension:: size_of_shape_checked ( & res_dim) ?;
354413
355414 if len_to_append == 0 {
@@ -468,7 +527,7 @@ impl<A, D> Array<A, D>
468527
469528 // With > 0 strides, the current end of data is the correct base pointer for tail_view
470529 let tail_ptr = self . data . as_end_nonnull ( ) ;
471- let mut tail_view = RawArrayViewMut :: new ( tail_ptr, array_shape , tail_strides) ;
530+ let mut tail_view = RawArrayViewMut :: new ( tail_ptr, array_dim , tail_strides) ;
472531
473532 if tail_view. ndim ( ) > 1 {
474533 sort_axes_in_default_order_tandem ( & mut tail_view, & mut array) ;
0 commit comments